diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2b01596..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: java -jdk: - - oraclejdk9 - - oraclejdk10 diff --git a/downloadContent/games.csv b/downloadContent/games.csv index d664a0e..3c414fc 100644 --- a/downloadContent/games.csv +++ b/downloadContent/games.csv @@ -32,34 +32,34 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101AE900,コナミ ワイワイレーシング アドバンス,WUP-N-PCTJ,v0,JAP, 00050000-101C5800,ポッ拳 POKKÉN TOURNAMENT,WUP-N-APKJ,v16,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/APKJ2P.jpg?1454770411 00050000-1015CA00,出たな!! ツインビー,WUP-N-PNXJ,v0,JAP, -00050000-1016BA00,???!!????,WUP-N-FC2J,v0,JAP, -00050000-10113600,???!???!???!,WUP-P-ATKJ,v0,JAP, -00050000-1012F200,???!???!???! (DL),WUP-N-WAKJ,v0,JAP, -00050000-101B8800,???!????,WUP-N-DAQJ,v0,JAP, -00050000-10188B00,???!???? ?????????,WUP-N-AXYJ,v16,JAP, -00050000-101B4100,???!amiibo ?????????????,WUP-N-AAVJ,v0,JAP, -00050000-1015C800,????,WUP-N-PNVJ,v0,JAP, -00050000-101D0D00,????,WUP-N-PDHJ,,JAP, -00050000-10197000,????,WUP-N-PB3J,v0,JAP, -00050000-10195200,????,WUP-N-MNXJ,,JAP, -00050000-10168B00,????,WUP-N-MNLJ,,JAP, -00050000-10168800,????,WUP-N-MNHJ,v0,JAP, -00050000-10168600,????,WUP-N-MNFJ,v0,JAP, -00050000-10191000,????,WUP-N-JC9J,v0,JAP, -00050000-10134600,????,WUP-N-JBCJ,v0,JAP, -00050000-10119F00,????,WUP-N-JATJ,v0,JAP, -00050000-10116400,????,WUP-N-HNAJ,v114,JAP, -00050000-10171100,????,WUP-N-FDAJ,v0,JAP, -00050000-1018B700,????,WUP-N-FD8J,v0,JAP, -00050000-1018B100,????,WUP-N-FD3J,v0,JAP, -00050000-10160400,????,WUP-N-FCPJ,v0,JAP, -00050000-1015F700,????,WUP-N-FCKJ,v0,JAP, -00050000-1015F600,????,WUP-N-FCJJ,v0,JAP, -00050000-10170E00,????,WUP-N-FC9J,v0,JAP, -00050000-10113E00,????,WUP-N-FALJ,v0,JAP, -00050000-1012E200,????,WUP-N-FA6J,v0,JAP, -00050000-1012A100,????,WUP-N-FA2J,v0,JAP, -00050000-101F3A00,????,WUP-N-BTXJ,,JAP, +00050000-1016BA00,燃えろ!!プロ野球,WUP-N-FC2J,v0,JAP, +00050000-10113600,タンク!タンク!タンク!,WUP-P-ATKJ,v0,JAP, +00050000-1012F200,タンク!タンク!タンク! (DL),WUP-N-WAKJ,v0,JAP, +00050000-101B8800,タッチ!カービィ ,WUP-N-DAQJ,v0,JAP, +00050000-10188B00,タッチ!カービィ スーパーレインボー,WUP-N-AXYJ,v16,JAP, +00050000-101B4100,タッチ!amiibo いきなりファミコン名シーン,WUP-N-AAVJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/AAVJ.jpg +00050000-1015C800,沙羅曼蛇,WUP-N-PNVJ,v0,JAP, +00050000-101D0D00,グランボ,WUP-N-PDHJ,,JAP, +00050000-10197000,逆転裁判,WUP-N-PB3J,v0,JAP, +00050000-10195200,ウシャス,WUP-N-MNXJ,,JAP, +00050000-10168B00,沙羅曼蛇,WUP-N-MNLJ,,JAP, +00050000-10168800,魔城伝説,WUP-N-MNHJ,v0,JAP, +00050000-10168600,クォース,WUP-N-MNFJ,v0,JAP, +00050000-10191000,魔神転生,WUP-N-JC9J,v0,JAP, +00050000-10134600,三國志Ⅳ,WUP-N-JBCJ,v0,JAP, +00050000-10119F00,超魔界村,WUP-N-JATJ,v0,JAP, +00050000-10116400,ニコニコ,WUP-N-HNAJ,v114,JAP, +00050000-10171100,へべれけ,WUP-N-FDAJ,v0,JAP, +00050000-1018B700,セクロス,WUP-N-FD8J,v0,JAP, +00050000-1018B100,月風魔伝,WUP-N-FD3J,v0,JAP, +00050000-10160400,サッカー,WUP-N-FCPJ,v0,JAP, +00050000-1015F700,影の伝説,WUP-N-FCKJ,v0,JAP, +00050000-1015F600,半熟英雄,WUP-N-FCJJ,v0,JAP, +00050000-10170E00,沙羅曼蛇,WUP-N-FC9J,v0,JAP, +00050000-10113E00,ゼビウス,WUP-N-FALJ,v0,JAP, +00050000-1012E200,ギャラガ,WUP-N-FA6J,v0,JAP, +00050000-1012A100,マッピー,WUP-N-FA2J,v0,JAP, +00050000-101F3A00,テラリア,WUP-N-BTXJ,,JAP, 00050000-101C9800,????,124,v0,JAP, 00050000-10194F00,???? ???,WUP-N-MNUJ,v0,JAP, 00050000-1014C300,???? ????,WUP-N-WKEJ,v0,JAP, @@ -81,7 +81,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101AEA00,???? 2,WUP-N-PCUJ,v0,JAP, 00050000-101C3B00,???? 3,WUP-N-PC6J,,JAP, 00050000-1018E300,???? R,WUP-N-PBSJ,v0,JAP, -00050000-101D2C00,???? Ultra DX - ?????,WUP-N-ATXJ,v1,JAP, +00050000-101D2C00,チャリ走 Ultra DX – 世界ツアー,WUP-N-ATXJ,v1,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ATXJ.jpg 00050000-10179D00,????!???!????!,98,v16,JAP, 00050000-101C8600,????!????,WUP-N-DAVJ,v0,JAP, 00050000-1016A600,????!?????????,WUP-N-WB6J,v17,JAP, @@ -199,22 +199,22 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101C3600,?????? ??????,105,v0,JAP, 00050000-10192200,?????? ??????!,WUP-P-BRSJ,v18,JAP, 00050000-1015E300,?????? ???????,WUP-N-PAKJ,v0,JAP, -00050000-101BAE00,?????? ???????,WUP-N-NANJ,,JAP, -00050000-1015D200,?????? ????????,WUP-N-PN7J,v0,JAP, -00050000-1016F300,?????? ????????,WUP-N-PATJ,v0,JAP, -00050000-101B1200,?????? ?????????,WUP-N-VAPJ,v0,JAP, -00050000-10109C00,?????? ?????????,WUP-N-JAEJ,v0,JAP, -00050000-10199000,?????? ?????????,WUP-N-AVXJ,v16,JAP, -00050000-10109700,?????? ??????????,WUP-N-JADJ,v0,JAP, -00050000-10170700,?????? ??????????,WUP-N-ABWJ,v17,JAP, -00050000-1019C800,?????? ??????????? HD,WUP-N-AZAJ,v82,JAP, -00050000-10153E00,?????? ???2,WUP-N-JB5J,v0,JAP, -00050000-10159300,?????? ???3,WUP-N-JB9J,v0,JAP, -00050000-1020AA00,?????? '93,WUP-N-PPTJ,,JAP, -00050000-1015C900,?????? '94,WUP-N-PNWJ,v0,JAP, -00050000-1015FE00,?????? ~????????~,WUP-N-JCCJ,v0,JAP, -00050000-10169800,?????? ~?????~,WUP-N-PANJ,v0,JAP, -00050000-101C5900,?????? 3-in-1,WUP-N-ATYJ,v0,JAP, +00050000-101BAE00,ゼルダの伝説 ムジュラの仮面,WUP-N-NANJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/NANJ.jpg +00050000-1015D200,ボンバーマン ぱにっくボンバー,WUP-N-PN7J,v0,JAP, +00050000-1016F300,星のカービィ 夢の泉デラックス,WUP-N-PATJ,v0,JAP, +00050000-101B1200,パンドラの塔 君のもとへ帰るまで,WUP-N-VAPJ,v0,JAP, +00050000-10109C00,星のカービィ スーパーデラックス,WUP-N-JAEJ,v0,JAP, +00050000-10199000,マリオテニス ウルトラスマッシュ,WUP-N-AVXJ,v16,JAP, +00050000-10109700,ゼルダの伝説 神々のトライフォース,WUP-N-JADJ,v0,JAP, +00050000-10170700,仮面ライダー バトライド・ウォーⅡ,WUP-N-ABWJ,v17,JAP, +00050000-1019C800,ゼルダの伝説 トワイライトプリンセス HD,WUP-N-AZAJ,v82,JAP, +00050000-10153E00,ロマンシング サ・ガ2,WUP-N-JB5J,v0,JAP, +00050000-10159300,ロマンシング サ・ガ3,WUP-N-JB9J,v0,JAP, +00050000-1020AA00,ボンバーマン '93,WUP-N-PPTJ,,JAP, +00050000-1015C900,ボンバーマン '94,WUP-N-PNWJ,v0,JAP, +00050000-1015FE00,マーヴェラス ~もうひとつの宝島~,WUP-N-JCCJ,v0,JAP, +00050000-10169800,風のクロノア ~夢見る帝国~,WUP-N-PANJ,v0,JAP, +00050000-101C5900,サイコロの森 3-in-1,WUP-N-ATYJ,v0,JAP, 00050000-101DA100,?????? 3on3,WUP-N-DA2J,,JAP, 00050000-10190100,?????? amiibo???????,WUP-P-AALJ,v0,JAP, 00050000-101D2B00,?????? AND CO.,WUP-N-ATCJ,v1,JAP, @@ -250,24 +250,24 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101CE300,???????,WUP-N-BNAJ,v0,JAP, 00050000-10112700,???????,WUP-N-ARBJ,v0,JAP, 00050000-1014F300,???????,WUP-N-APCJ,v0,JAP, -00050000-101A7900,???????,99,v0,JAP, -00050000-10186200,???????,116,v0,JAP, -00050000-10186B00,??????? ? ???,WUP-N-JC4J,v0,JAP, -00050000-10157C00,??????? ?????,WUP-N-WGEJ,v1,JAP, -00050000-1014F400,??????? ?????,WUP-N-WCKJ,v0,JAP, -00050000-1019CE00,??????? ?????,WUP-N-VABJ,v0,JAP, -00050000-101D8B00,??????? ?????,WUP-N-AP8J,v0,JAP, -00050000-10190700,??????? ??????,WUP-N-FECJ,v0,JAP, -00050000-1018B600,??????? ????????,WUP-N-FD7J,v0,JAP, -00050000-10113100,??????? ???????? ?????? ??????,WUP-N-ABHJ,v16,JAP, -00050000-101A5A00,??????? ?????????,WUP-N-NAHJ,v0,JAP, -00050000-1F600900,??????? ?????????,WUP-N-CNFJ,,JAP, -00050000-10144800,??????? ?????????,WUP-N-ARKJ,v17,JAP, -00050000-101A5200,??????? ??????????,WUP-N-DAJJ,v1,JAP, -00050000-10188000,??????? ???????????,WUP-N-PBMJ,v0,JAP, -00050000-10113000,??????? 3 - ??? -,WUP-P-AMEJ,v16,JAP, -00050000-10106100,??????? 3D????,WUP-N-ARDJ,v1,JAP, -00050000-101E9C00,???????:??????????,WUP-N-ACUJ,,JAP, +00050000-101A7900,キングスナイト,99,v0,JAP, +00050000-10186200,マッド・シティ,116,v0,JAP, +00050000-10186B00,コズモギャング ザ パズル,WUP-N-JC4J,v0,JAP, +00050000-10157C00,アルファディア ジェネシス,WUP-N-WGEJ,v1,JAP, +00050000-1014F400,クラウドベリー キングダム,WUP-N-WCKJ,v0,JAP, +00050000-1019CE00,ドンキーコング リターンズ,WUP-N-VABJ,v0,JAP, +00050000-101D8B00,ヒラメキパズル テトグラム,WUP-N-AP8J,v0,JAP, +00050000-10190700,バイオミラクル ぼくってウパ,WUP-N-FECJ,v0,JAP, +00050000-10190700,すごろクエスト ダイスの戦士たち,WUP-N-FD7J,v0,JAP, +00050000-10113100,バイオハザード リベレーションズ アンベールド エディション,WUP-N-ABHJ,v16,JAP, +00050000-101A5A00,テン・エイティ スノーボーディング,WUP-N-NAHJ,v0,JAP, +00050000-1F600900,ペーパーマリオ カラースプラッシュ,WUP-N-CNFJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/CNFJ01.jpg +00050000-10144800,ドンキーコング トロピカルフリーズ,WUP-N-ARKJ,v17,JAP, +00050000-101A5200,ドンキーコング ジャングルクライマ,WUP-N-DAJJ,v1,JAP, +00050000-10188000,ことばのパズル もじぴったんアドバンス,WUP-N-PBMJ,v0,JAP, +00050000-10113000,マスエフェクト 3 - 特別版 -,WUP-P-AMEJ,v16,JAP, +00050000-10106100,スーパーマリオ 3Dワールド,WUP-N-ARDJ,v1,JAP, +00050000-101E9C00,キューブライフ:アイランドサバイバル,WUP-N-ACUJ,,JAP, 00050000-10176700,???????!,WUP-N-WKMJ,v0,JAP, 00050000-101CAA00,???????!????VS????,WUP-N-WMMJ,v0,JAP, 00050000-101B3000,???????!(??????????2014 ?????),WUP-N-BMJJ,v0,JAP, @@ -527,12 +527,12 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101AC300,????????64,104,v0,JAP, 00050000-10163F00,????????II,WUP-N-PPFJ,,JAP, 00050000-1017B800,????????SP,WUP-N-WBWJ,v1,JAP, -00050000-101FD300,????????U,WUP-N-WBUJ,,JAP, -00050000-101B3400,????????X ????????? ?????,WUP-P-BDLJ,,JAP, -00050000-10115E00,????????X ????????? ?????,WUP-N-ADQJ,v1312,JAP, -00050000-10155F00,????????X ??????????? ?????,WUP-P-ANYJ,,JAP, -00050000-1015FF00,????????XX,WUP-N-JCDJ,v0,JAP, -00050000-101A0200,????????Z,112,v0,JAP, +00050000-101FD300,ブロークドロップU,WUP-N-WBUJ,,JAP,https://art.gametdb.com/wiiu/coverM/JA/WBUJ.jpg +00050000-101B3400,ドラゴンクエストⅩ いにしえの竜の伝承 オンライン,WUP-P-BDLJ,,JAP, +00050000-10115E00,ドラゴンクエストⅩ 目覚めし五つの種族 オンライン,WUP-N-ADQJ,v1312,JAP, +00050000-10155F00,ドラゴンクエストⅩ 眠れる勇者と導きの盟友 オンライン,WUP-P-ANYJ,,JAP, +00050000-1015FF00,悪魔城ドラキュラXX,WUP-N-JCDJ,v0,JAP, +00050000-101A0200,フォーメーションZ,112,v0,JAP, 00050000-101B3100,???????(??????????2014 ?????),WUP-N-BYSJ,v0,JAP, 00050000-101B3600,???????(??????????2014 ?????),WUP-N-ALTJ,v0,JAP, 00050000-10161F00,???????10,WUP-N-ABAJ,v16,JAP, @@ -569,7 +569,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10184200,??????G2 ???????????????,WUP-N-PBKJ,v0,JAP, 00050000-10141500,??????if...,WUP-N-JBSJ,v0,JAP, 00050000-1015C000,??????II,WUP-N-PNMJ,v0,JAP, -00050000-101C5E00,??????V2,WUP-N-NARJ,,JAP, +00050000-101C5E00,カスタムロボV2,WUP-N-NARJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/NARJ.jpg 00050000-1018E600,?????&????,WUP-N-PBTJ,v0,JAP, 00050000-1011B900,?????2,WUP-N-AQUJ,v1,JAP, 00050000-10114700,?????2 Dr.??????,WUP-N-FAPJ,v0,JAP, @@ -686,8 +686,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101DBF00,Angry Video Game Nerd Adventures,WUP-P-AVGP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AVGE.jpg?1475529340 00050000-1018F400,Angry Video Game Nerd Adventures,WUP-N-AVGE,v1,USA,https://art.gametdb.com/wiiu/coverHQ/US/AVGE.jpg?1475529340 00050000-10145600,Animal Crossing Plaza,WUP-U-ADBA,v16,all,https://art.gametdb.com/wiiu/coverHQ/EN/ADBP.jpg?1463010434 -00050000-101C6500,Animal Crossing: amiibo Festival,WUP-P-AALP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AALE01.jpg?1451062877 -00050000-101C6400,Animal Crossing: amiibo Festival,WUP-P-AALE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AALE01.jpg?1451062877 +00050000-101C6500,Animal Crossing: amiibo Festival,WUP-P-AALP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AALP01.jpg +00050000-101C6400,Animal Crossing: amiibo Festival,WUP-P-AALE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AALE01.jpg 00050000-101D2100,Animal Crossing: Wild World,WUP-N-DAYP,,EUR, 00050000-101D2000,Animal Crossing: Wild World,WUP-N-DAYE,,USA, 00050000-10173200,Another World - 20th Anniversary Edition,WUP-P-WEUP,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WEUE.jpg?1469834113 @@ -955,15 +955,15 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10174700,Dig Dug,WUP-N-FDEE,v0,USA, 00050000-101A7800,Dig Dug II,WUP-N-FEWP,v0,EUR, 00050000-101A7700,Dig Dug II,WUP-N-FEWE,,USA, -00050000-1018A700,Dinox,WUP-P-BDNP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BDNE.jpg?1476388120 -00050000-1018F500,Dinox,WUP-N-BDNE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BDNE.jpg?1476388120 -00050000-101E8300,Discovery,WUP-P-ADUP,,EUR, -00050000-101D9B00,Discovery,WUP-N-ADUE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 -00050000-10112E00,Disney Epic Mickey 2,18,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 -00050000-1012C400,Disney Epic Mickey 2,19,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 -00050000-10136D00,Disney Epic Mickey 2,20,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 -00050000-1011B000,Disney Epic Mickey 2: The Power of Two,WUP-P-AEMS,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 -00050000-1010DB00,Disney Epic Mickey 2: The Power of Two,WUP-N-AEME,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg?1355066365 +00050000-1018A700,Dinox,WUP-P-BDNP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BDNE.jpg +00050000-1018F500,Dinox,WUP-N-BDNE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BDNE.jpg +00050000-101E8300,Discovery,WUP-P-ADUP,,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/ADUP.jpg +00050000-101D9B00,Discovery,WUP-N-ADUE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADUE.jpg +00050000-10112E00,Disney Epic Mickey 2,18,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg +00050000-1012C400,Disney Epic Mickey 2,19,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg +00050000-10136D00,Disney Epic Mickey 2,20,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/AEMJ91.jpg +00050000-1011B000,Disney Epic Mickey 2: The Power of Two,WUP-P-AEMS,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AEMS4Q.jpg +00050000-1010DB00,Disney Epic Mickey 2: The Power of Two,WUP-N-AEME,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AEME4Q.jpg 00050000-10137000,Disney Infinity,WUP-U-ADSZ,v49,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADSE4Q.jpg?1385299887 00050000-10136F00,Disney Infinity,WUP-U-ADSP,v49,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADSE4Q.jpg?1385299887 00050000-10132900,Disney Infinity,WUP-P-ADSE,v49,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADSE4Q.jpg?1385299887 @@ -981,12 +981,12 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101A5300,DK Jungle Climber,WUP-N-DAJE,v1,USA, 00050000-1017D700,DK: King of Swing,WUP-N-PBCP,v0,EUR, 00050000-1017D600,DK: King of Swing,WUP-N-PBCE,v0,USA, -00050000-101A8100,Dodge Club Party,WUP-N-BDGE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BDGE.jpg?1488459948 -00050000-1017DB00,Dolphin Up,WUP-N-WUPE,v16,USA, -00050000-101D2800,DON'T CRASH,WUP-N-AC5E,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AC5E.jpg?1475792756 -00050000-101C9A00,Don't Starve: Giant Edition,WUP-P-ADAP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADAE.jpg?1475792710 -00050000-101C4300,Don't Starve: Giant Edition,WUP-N-ADAE,v1,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADAE.jpg?1475792710 -00050000-1018EE00,Don't Touch Anything Red,WUP-N-ANTE,v1,USA,https://art.gametdb.com/wiiu/coverHQ/US/ANTE.jpg?1488461986 +00050000-101A8100,Dodge Club Party,WUP-N-BDGE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BDGE.jpg +00050000-1017DB00,Dolphin Up,WUP-N-WUPE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/US/WUPE.jpg +00050000-101D2800,DON'T CRASH,WUP-N-AC5E,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AC5E.jpg +00050000-101C9A00,Don't Starve: Giant Edition,WUP-P-ADAP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADAE.jpg +00050000-101C4300,Don't Starve: Giant Edition,WUP-N-ADAE,v1,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADAE.jpg +00050000-1018EE00,Don't Touch Anything Red,WUP-N-ANTE,v1,USA,https://art.gametdb.com/wiiu/coverHQ/US/ANTE.jpg 00050000-10108000,Donkey Kong,WUP-N-FAFP,v0,EUR, 00050000-10107F00,Donkey Kong,WUP-N-FAFE,v0,USA, 00050000-1014A900,Donkey Kong 3,WUP-N-FBRP,v0,EUR, @@ -1025,7 +1025,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10152A00,Dr. Luigi,WUP-N-WAQE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WAQE.jpg?1476819557 00050000-10153200,Dr. Mario,WUP-N-FB5P,v0,EUR,https://art.gametdb.com/wii/cover/US/WDME.png?1353446316 00050000-10153100,Dr. Mario,WUP-N-FB5E,v0,USA,https://art.gametdb.com/wii/cover/US/WDME.png?1353446316 -00050000-10150300,Dr.LUIGI & 細菌撲滅,WUP-N-WAQJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/US/WAQE.jpg?1476819557 +00050000-10150300,Dr.LUIGI & 細菌撲滅,WUP-N-WAQJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/WAQJ.jpg 00050000-101F4F00,Dracula's Legacy,WUP-P-AGJP,,EUR,https://art.gametdb.com/wiiu/coverM/US/AGJE.jpg?1476537791 00050000-101F5000,Dracula's Legacy,WUP-N-AGJE,,USA,https://art.gametdb.com/wiiu/coverM/US/AGJE.jpg?1476537791 00050000-101B2900,Dragon Fantasy: The Black Tome of Ice,WUP-N-AFYE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AFYE.jpg?1475792823 @@ -1040,17 +1040,17 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10203B00,Dreamals: Dream Quest,WUP-N-AQBE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AQBE.jpg?1488462612 00050000-101CAF00,Drill Dozer,WUP-N-PDEP,,EUR, 00050000-101CB000,Drill Dozer,WUP-N-PDEE,,USA, -00050000-101F7600,Dual Core,WUP-P-BD8P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BD8E.jpg?1475793254 -00050000-101E3800,Dual Core,WUP-N-BD8E,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BD8E.jpg?1475793254 +00050000-101F7600,Dual Core,WUP-P-BD8P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BD8E.jpg +00050000-101E3800,Dual Core,WUP-N-BD8E,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BD8E.jpg 00050000-10192600,Duck Hunt,WUP-N-FEHP,v1,EUR, 00050000-10192500,Duck Hunt,WUP-N-FEHE,v1,USA, -00050000-10129200,DuckTales: Remastered,WUP-P-WDKP,v32,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WDKE08.jpg?1458757418 -00050000-10129000,DuckTales: Remastered,WUP-N-WDKE,v32,USA,https://art.gametdb.com/wiiu/coverHQ/US/WDKE08.jpg?1458757418 +00050000-10129200,DuckTales: Remastered,WUP-P-WDKP,v32,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WDKE08.jpg +00050000-10129000,DuckTales: Remastered,WUP-N-WDKE,v32,USA,https://art.gametdb.com/wiiu/coverHQ/US/WDKE08.jpg 00050000-10167700,Dungeon Explorer,WUP-N-PN3E,,USA, 00050000-101F8A00,Dungeon Hearts DX,WUP-N-BXDE,,USA, -00050000-1012BF00,Dungeons & Dragons: Chronicles of Mystara,WUP-P-WDDP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WDDE.jpg?1475793358 -00050000-1012C000,Dungeons & Dragons: Chronicles of Mystara,WUP-N-WDDE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WDDE.jpg?1475793358 -00050000-1010D900,EA SPORTS FIFA Soccer 13,WUP-N-AF3E,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AF3E69.jpg?1355512715 +00050000-1012BF00,Dungeons & Dragons: Chronicles of Mystara,WUP-P-WDDP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WDDE.jpg +00050000-1012C000,Dungeons & Dragons: Chronicles of Mystara,WUP-N-WDDE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WDDE.jpg +00050000-1010D900,EA SPORTS FIFA Soccer 13,WUP-N-AF3E,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AF3E69.jpg 00050000-10133500,EarthBound,WUP-N-JBBP,v0,EUR, 00050000-10133400,EarthBound,WUP-N-JBBE,v0,USA, 00050000-10133200,EarthBound Beginnings,WUP-N-FBDP,v0,EUR, @@ -1117,7 +1117,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-1012F000,FAST Racing NEO,WUP-N-WFSE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/WFSE.jpg?1475794541 00050000-101FED00,FAST Racing NEO,WUP-P-BR5P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WFSE.jpg?1475794541 00050000-10182D00,Fat City,WUP-N-AFTE,v1,USA, -00050000-101D0600,Fatal Frame: Maiden of Black Water,WUP-N-AL5E,v0,USA, +00050000-101D0600,Fatal Frame: Maiden of Black Water,WUP-N-AL5E,v0,USA,https://art.gametdb.com/wiiu/coverM/US/AL5E.jpg 00050000-1FBF1000,FBF10,WUP-P-ABCD,"v0, v32 ",all, 00050000-1010EE00,FIFA 13,WUP-P-AF3P,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AF3P69.jpg?1458686491 00050000-10110C00,FIFA 13 ワールドクラスサッカー,WUP-N-AF3J,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/EN/AF3P69.jpg?1458686491 @@ -1278,8 +1278,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10150500,Ice Hockey,WUP-N-FBUE,v0,USA, 00050000-10184400,Infinity Runner,WUP-P-BRNP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BRNE.jpg?1475871864 00050000-10183C00,Infinity Runner,WUP-N-BRNE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BRNE.jpg?1475871864 -00050000-10111A00,Injustice: Gods Among Us,WUP-P-AJSP,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AJSPWR.jpg?1384898050 -00050000-10111700,Injustice: Gods Among Us,WUP-N-AJSE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/EN/AJSPWR.jpg?1384898050 +00050000-10111A00,Injustice: Gods Among Us,WUP-P-AJSP,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AJSPWR.jpg +00050000-10111700,Injustice: Gods Among Us,WUP-N-AJSE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/US/AJSEWR.jpg 00050000-101E5800,Inside My Radio,WUP-P-ARQP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ARQE.jpg?1475872012 00050000-101E5A00,Inside My Radio,WUP-N-ARQE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/ARQE.jpg?1475872012 00050000-10179300,Internal Invasion,WUP-N-WG9E,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WG9E.jpg?1469833806 @@ -1399,12 +1399,12 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101DAB00,LEGO Star Wars: The Force Awakens,WUP-N-BLGE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BLGEWR.jpg?1471068273 00050000-10168D00,LEGO The Hobbit,WUP-P-ALHP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ALHEWR.jpg?1447095190 00050000-1016A700,LEGO The Hobbit,WUP-N-ALHE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/ALHEWR.jpg?1447095190 -00050000-10192100,LEGO ムービー ザ・ゲーム,WUP-N-ALAJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALAJWR.jpg?1458328106 -00050000-101EA100,LEGO マーベル アベンジャーズ,WUP-N-ALRJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/US/ALREWR.jpg?1454429385 -00050000-101A2D00,LEGO マーベル スーパー・ヒーローズ ザ・ゲーム,WUP-N-ALMJ,v1,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALMJWR.jpg?1458326377 -00050000-101CDF00,LEGO ジュラシック・ワールド,WUP-N-ALJJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALJJWR.jpg?1458326309 -00050000-101EA000,LEGO スター・ウォーズ/フォースの覚醒,WUP-N-BLGJ,,JAP,https://art.gametdb.com/wiiu/coverM/JA/BLGJWR.jpg?1476282662 -00050000-101B2700,LEGO バットマン3 ザ・ゲーム ゴッサムから宇宙へ,WUP-N-BTMJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/BTMJWR.jpg?1458326334 +00050000-10192100,LEGO ムービー ザ・ゲーム,WUP-N-ALAJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALAJWR.jpg +00050000-101EA100,LEGO マーベル アベンジャーズ,WUP-N-ALRJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALRJWR.jpg +00050000-101A2D00,LEGO マーベル スーパー・ヒーローズ ザ・ゲーム,WUP-N-ALMJ,v1,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALMJWR.jpg +00050000-101CDF00,LEGO ジュラシック・ワールド,WUP-N-ALJJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ALJJWR.jpg +00050000-101EA000,LEGO スター・ウォーズ/フォースの覚醒,WUP-N-BLGJ,,JAP,https://art.gametdb.com/wiiu/coverM/JA/BLGJWR.jpg +00050000-101B2700,LEGO バットマン3 ザ・ゲーム ゴッサムから宇宙へ,WUP-N-BTMJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/BTMJWR.jpg 00050000-101F6400,Letter Quest Remastered,WUP-P-AG8P,,EUR, 00050000-101F5500,Letter Quest: Remastered,WUP-N-AG8E,,USA, 00050000-101D3B00,Level 22,WUP-P-AL2P,,EUR, @@ -1436,8 +1436,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101EAE00,Lucentek Beyond,WUP-P-WLBE,,USA, 00050000-10154E00,Luv Me Buddies Wonderland,WUP-P-ALVP,v1,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/ALVPYF.jpg?1475665205 00050000-10177400,Luv Me Buddies Wonderland,WUP-N-ALVE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/EN/ALVPYF.jpg?1475665205 -00050000-10190300,Mario & Sonic at the Rio 2016 Olympic Games,WUP-U-ABJJ,48,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ABJJ01.jpg?1463240667 -00050000-101E5300,Mario & Sonic at the Rio 2016 Olympic Games,WUP-U-ABJE,16,USA,https://art.gametdb.com/wiiu/coverHQ/JA/ABJJ01.jpg?1463240667 +00050000-10190300,Mario & Sonic at the Rio 2016 Olympic Games,WUP-U-ABJJ,48,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/ABJJ01.jpg +00050000-101E5300,Mario & Sonic at the Rio 2016 Olympic Games,WUP-U-ABJE,16,USA,https://art.gametdb.com/wiiu/coverHQ/EN/ABJP01.jpg 00050000-10160900,Mach Rider,WUP-N-FCQP,v0,EUR, 00050000-10160800,Mach Rider,WUP-N-FCQE,v0,USA, 00050000-1010D800,Madden NFL 13,WUP-N-AMDE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/AMDE69.jpg?1354294756 @@ -1449,7 +1449,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101A2200,Mario & Luigi: Partners in Time,WUP-N-DAHE,v0,USA, 00050000-10157500,Mario & Luigi: Superstar Saga,WUP-N-PAEP,v0,EUR, 00050000-10157400,Mario & Luigi: Superstar Saga,WUP-N-PAEE,v1,USA, -00050000-101E5400,Mario & Sonic at the Rio 2016 Olympic Games,WUP-P-ABJP,,EUR,https://art.gametdb.com/wiiu/coverHQ/JA/ABJJ01.jpg?1463240667 +00050000-101E5400,Mario & Sonic at the Rio 2016 Olympic Games,WUP-P-ABJP,,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/ABJP01.jpg 00050000-1010C800,Mario & Sonic at the Sochi 2014 Olympic Winter Games,WUP-P-AURP,v32,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AURP01.jpg?1384710496 00050000-1010C700,Mario & Sonic at the Sochi 2014 Olympic Winter Games,WUP-P-AURE,v32,USA,https://art.gametdb.com/wiiu/coverHQ/EN/AURP01.jpg?1384710496 00050000-10107C00,Mario Bros.,WUP-N-FAEE,v0,USA, @@ -1595,8 +1595,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-101C5A00,Mighty No. 9,WUP-P-AMQP,,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AMQPKM.jpg?1466700278 00050000-101DD900,Mighty No. 9,WUP-N-AMQJ,,JAP,https://art.gametdb.com/wiiu/coverHQ/EN/AMQPKM.jpg?1466700278 00050000-101C9600,Mighty No. 9,WUP-N-AMQE,,USA,https://art.gametdb.com/wiiu/coverHQ/EN/AMQPKM.jpg?1466700278 -00050000-1014F100,Mighty Switch Force! 2,WUP-P-WM2P,v0,EUR,https://art.gametdb.com/wiiu/coverM/US/WM2E.jpg?1404311990 -00050000-1014FC00,Mighty Switch Force! 2,WUP-N-WM2E,v0,USA,https://art.gametdb.com/wiiu/coverM/US/WM2E.jpg?1404311990 +00050000-1014F100,Mighty Switch Force! 2,WUP-P-WM2P,v0,EUR,https://art.gametdb.com/wiiu/coverM/US/WM2E.jpg +00050000-1014FC00,Mighty Switch Force! 2,WUP-N-WM2E,v0,USA,https://art.gametdb.com/wiiu/coverM/US/WM2E.jpg 00050000-10128200,Mighty Switch Force! Hyper Drive Edition,WUP-P-WHYP,v32,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WHYE.jpg?1469834303 00050000-1011B100,Mighty Switch Force! Hyper Drive Edition,WUP-N-WHYE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/US/WHYE.jpg?1469834303 00050000-10205500,MikroGame: Rotator,WUP-P-BR7P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BR7E.jpg?1475874112 @@ -1741,7 +1741,7 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10175C00,One Piece: Unlimited World Red,WUP-N-AUNE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/JA/AUNJAF.jpg?1459438484 00050000-101A9200,Onimusha Tactics,WUP-N-PCKP,,EUR, 00050000-101A9300,Onimusha Tactics,WUP-N-PCKE,v0,USA, -00050000-101AB100,Outer World 20th Anniversary Edition,WUP-N-WEUJ,v0,JAP, +00050000-101AB100,Outer World 20th Anniversary Edition,WUP-N-WEUJ,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/WEUJ.jpg 00050000-101D0800,Outside the Realm,WUP-N-ARLE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/ARLE.jpg?1488257330 00050000-10202100,Overworld Defender Remix,WUP-N-BR8E,,USA, 00050000-10186D00,Pac-Attack,WUP-N-JC4P,v0,EUR, @@ -2104,23 +2104,23 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10135200,Star Wars Pinball,WUP-N-WA2E,v33,USA,https://art.gametdb.com/wiiu/coverHQ/US/WA2E.jpg?1476384312 00050000-101B5B00,StarTropics,WUP-N-FE2P,v0,EUR, 00050000-101B5A00,StarTropics,WUP-N-FE2E,,USA, -00050000-101D4700,STARWHAL,WUP-P-BJTP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BJTE.jpg?1476043031 -00050000-1019ED00,STARWHAL,WUP-N-BJTE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/BJTE.jpg?1476043031 -00050000-10173300,Stealth Inc 2: A Game of Clones,WUP-P-WCGP,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WCGE.jpg?1476043150 -00050000-10176500,Stealth Inc 2: A Game of Clones,WUP-N-WCGE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/US/WCGE.jpg?1476043150 -00050000-1018D800,SteamWorld Dig,WUP-P-ADGP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADGE.jpg?1476043255 -00050000-1018F100,SteamWorld Dig,WUP-N-ADGE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADGE.jpg?1476043255 -00050000-101A3700,SteamWorld Heist,WUP-P-AY5P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AY5E.jpg?1476052479 -00050000-101A4000,SteamWorld Heist,WUP-N-AY5E,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AY5E.jpg?1476052479 -00050000-101FDE00,STEEL LORDS,WUP-P-ALQP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ALQE.jpg?1476559837 -00050000-101FE500,STEEL LORDS,WUP-N-ALQE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/ALQE.jpg?1476559837 -00050000-101F1600,STEEL RIVALS,WUP-P-BRCP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BRCE.jpg?1476800242 -00050000-101D9500,STEEL RIVALS,WUP-N-BRCE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BRCE.jpg?1476800242 -00050000-1016D400,Stick it to the Man,WUP-P-WMNP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WMNE.jpg?1476043351 -00050000-1016E000,Stick it to the Man,WUP-N-WMNE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WMNE.jpg?1476043351 +00050000-101D4700,STARWHAL,WUP-P-BJTP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BJTE.jpg +00050000-1019ED00,STARWHAL,WUP-N-BJTE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/BJTE.jpg +00050000-10173300,Stealth Inc 2: A Game of Clones,WUP-P-WCGP,v16,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WCGE.jpg +00050000-10176500,Stealth Inc 2: A Game of Clones,WUP-N-WCGE,v16,USA,https://art.gametdb.com/wiiu/coverHQ/US/WCGE.jpg +00050000-1018D800,SteamWorld Dig,WUP-P-ADGP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ADGE.jpg +00050000-1018F100,SteamWorld Dig,WUP-N-ADGE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/ADGE.jpg +00050000-101A3700,SteamWorld Heist,WUP-P-AY5P,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AY5E.jpg +00050000-101A4000,SteamWorld Heist,WUP-N-AY5E,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AY5E.jpg +00050000-101FDE00,STEEL LORDS,WUP-P-ALQP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/ALQE.jpg +00050000-101FE500,STEEL LORDS,WUP-N-ALQE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/ALQE.jpg +00050000-101F1600,STEEL RIVALS,WUP-P-BRCP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BRCE.jpg +00050000-101D9500,STEEL RIVALS,WUP-N-BRCE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/BRCE.jpg +00050000-1016D400,Stick it to the Man,WUP-P-WMNP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WMNE.jpg +00050000-1016E000,Stick it to the Man,WUP-N-WMNE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/WMNE.jpg 00050000-1018B500,STINGER,WUP-N-FD6E,v0,USA, -00050000-101D5100,Stone Shire,WUP-P-BSVP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BSVE.jpg?1475925595 -00050000-101A4C00,Stone Shire,WUP-N-BSVE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/BSVE.jpg?1475925595 +00050000-101D5100,Stone Shire,WUP-P-BSVP,v0,EUR,https://art.gametdb.com/wiiu/coverHQ/US/BSVE.jpg +00050000-101A4C00,Stone Shire,WUP-N-BSVE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/BSVE.jpg 00050000-10177F00,Street Fighter 2010: The Final Fight,WUP-N-FDLP,v0,EUR, 00050000-10177E00,Street Fighter 2010: The Final Fight,WUP-N-FDLE,v0,USA, 00050000-1016C600,Street Fighter Alpha 2,WUP-N-JCGP,v0,EUR, @@ -2139,8 +2139,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10130B00,Super Castlevania IV,WUP-N-JA9P,v0,EUR, 00050000-10130A00,Super Castlevania IV,WUP-N-JA9E,v0,USA, 00050000-101B9600,Super Destronaut,WUP-N-ASJE,v0,USA,https://art.gametdb.com/wiiu/coverHQ/US/ASJE.jpg?1476907451 -00050000-101FB000,Super Destronaut 2: Go Duck Yourself,WUP-P-AJNP,,EUR,https://art.gametdb.com/wiiu/coverHQ/US/AJNE.jpg?1477517957 -00050000-101F9400,Super Destronaut 2: Go Duck Yourself,WUP-N-AJNE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AJNE.jpg?1477517957 +00050000-101FB000,Super Destronaut 2: Go Duck Yourself,WUP-P-AJNP,,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/AJNP.jpg +00050000-101F9400,Super Destronaut 2: Go Duck Yourself,WUP-N-AJNE,,USA,https://art.gametdb.com/wiiu/coverHQ/US/AJNE.jpg 00050000-10151200,Super Dodge Ball,WUP-N-FB2P,v0,EUR, 00050000-10151100,Super Dodge Ball,WUP-N-FB2E,v0,USA, 00050000-10191100,SUPER E.D.F. Earth Defense Force,WUP-N-JDAJ,v0,JAP, @@ -2480,8 +2480,8 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-1012F100,Wii Sports Club,WUP-N-AWSJ,v112,JAP,https://art.gametdb.com/wiiu/coverHQ/US/AWSE01.jpg?1469542427 00050000-10144D00,Wii Sports Club,WUP-N-AWSE,v112,USA,https://art.gametdb.com/wiiu/coverHQ/US/AWSE01.jpg?1469542427 00050000-10171E00,Wii Sports Club Lite,90,v0,JAP,https://art.gametdb.com/wiiu/coverHQ/US/AWSE01.jpg?1469542427 -00050000-1012D300,Wii Street U powered by Google,WUP-N-WHXJ,v144,JAP,https://art.gametdb.com/wiiu/coverHQ/US/WHXE.jpg?1476395180 -00050000-10132000,Wii Street U powered by Google,91,v144,USA,https://art.gametdb.com/wiiu/coverHQ/US/WHXE.jpg?1476395180 +00050000-1012D300,Wii Street U powered by Google,WUP-N-WHXJ,v144,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/WHXJ.jpg +00050000-10132000,Wii Street U powered by Google,WUP-N-WHXE,v144,USA,https://art.gametdb.com/wiiu/coverHQ/US/WHXE.jpg 00050000-10132100,Wii Street U powered by Google,92,v144,EUR,https://art.gametdb.com/wiiu/coverHQ/US/WHXE.jpg?1476395180 00050000-10129600,Wii U Panorama View 予告編,WUP-N-SPGJ,v1,JAP,https://art.gametdb.com/wiiu/coverM/JA/SPGJ.jpg?1419725497 00050000-1012D500,Wii U Panorama View 鳥の飛行隊,WUP-N-WETJ,v1,JAP,https://art.gametdb.com/wiiu/coverM/JA/WETJ.jpg?1419725020 @@ -2576,3 +2576,9 @@ TitleID,Description,ProductCode,Version,Region,CoverURL 00050000-10112300,ZombiU(ゾンビU),WUP-N-AZUJ,v32,JAP,https://art.gametdb.com/wiiu/coverHQ/US/AZUE41.jpg?1354294751 00050000-1014E300,Zumba Fitness World Party,WUP-U-AZBP,v16,EUR,https://art.gametdb.com/wii/cover/EN/SZ3PGT.png?1385155346 00050000-10142A00,Zumba Fitness World Party,WUP-N-AZBE,v16,USA,https://art.gametdb.com/wii/cover/EN/SZ3PGT.png?1385155346 +00050000-10217000,JUST DANCE® 2019,WUP-P-HJDP,16,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/HJDP41.jpg +00050000-10217300,JUST DANCE® 2019,WUP-P-HJDE,"16, 32, 48, 64, 80, 96, 113, 128, 144, 160, 176, 192, 208, 224 ",USA,https://art.gametdb.com/wiiu/coverHQ/EN/HJDP41.jpg +00050000-10209900,Cars 3: Driven to Win,WUP-N-BA4E,,USA,https://art.gametdb.com/wiiu/coverHQ/DE/BA4PWR.jpg +00050000-1020A400,Cars 3: Driven to Win,WUP-P-BA4P,,EUR,https://art.gametdb.com/wiiu/coverHQ/DE/BA4PWR.jpg +00050000-10211F00,ドラゴンクエストⅩ 5000年の旅路 遙かなる故郷へ オンライン,WUP-P-AXTJ ,,JAP,https://art.gametdb.com/wiiu/coverHQ/JA/AXTJGD.jpg +00050000-10210C00,Just Dance 2018®,WUP-P-BJ8P,,EUR,https://art.gametdb.com/wiiu/coverHQ/EN/BJ8P41.jpg diff --git a/pom.xml b/pom.xml index b340728..99f6050 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com cemu_UI - 0.3.1-SNAPSHOT + 0.3.2-SNAPSHOT jar cemu_UI cemu_UI is a simple, material design graphical frontend for cemu, a Wii U emulator @@ -27,25 +27,25 @@ org.openjfx javafx-controls - 11 + 12.0.1 org.openjfx javafx-fxml - 11 + 12.0.1 org.openjfx javafx-media - 11 + 12.0.1 com.jfoenix jfoenix - 9.0.6 + 9.0.9 @@ -57,19 +57,19 @@ org.xerial sqlite-jdbc - 3.23.1 + 3.27.2.1 org.apache.logging.log4j log4j-api - 2.11.1 + 2.11.2 org.apache.logging.log4j log4j-core - 2.11.1 + 2.11.2 @@ -92,14 +92,6 @@ 1.11 - - - io.datafx - flow - 8.0.1 - - - net.lingala.zip4j @@ -115,18 +107,11 @@ 1.1.1 - - - com.google.api-client - google-api-client - 1.25.0 - - com.google.apis google-api-services-drive - v3-rev129-1.25.0 + v3-rev136-1.25.0 @@ -143,20 +128,6 @@ 1.25.0 - - - com.google.oauth-client - google-oauth-client - 1.25.0 - - - - - com.google.oauth-client - google-oauth-client-java6 - 1.25.0 - - com.google.oauth-client @@ -168,15 +139,7 @@ com.fasterxml.jackson.core jackson-core - 2.9.6 - - - - - javax.servlet - javax.servlet-api - 4.0.1 - provided + 2.9.7 @@ -186,13 +149,6 @@ 6.1.26 - - - org.mortbay.jetty - jetty-util - 6.1.26 - - @@ -229,7 +185,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.1 + 3.2.1 package diff --git a/src/main/java/com/cemu_UI/application/Main.java b/src/main/java/com/cemu_UI/application/Main.java index caf7a6a..c704425 100644 --- a/src/main/java/com/cemu_UI/application/Main.java +++ b/src/main/java/com/cemu_UI/application/Main.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.application; import java.io.File; @@ -26,7 +27,6 @@ import java.io.IOException; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; -import java.util.Optional; import java.util.Timer; import java.util.TimerTask; @@ -34,51 +34,44 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.cemu_UI.controller.CloudController; +import com.cemu_UI.controller.XMLController; +import com.cemu_UI.uiElements.JFXInfoAlert; +import com.cemu_UI.uiElements.JFXOkayCancelAlert; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXMLLoader; -import javafx.stage.DirectoryChooser; -import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; import javafx.scene.control.Alert.AlertType; import javafx.scene.layout.AnchorPane; +import javafx.stage.DirectoryChooser; +import javafx.stage.Stage; public class Main extends Application { - private Stage primaryStage; + private final String gamesDBdownloadURL = "https://git.mosad.xyz/Seil0/cemu_UI/raw/branch/master/downloadContent/games.db"; + private static Main main; + private static XMLController xmlController; private MainWindowController mainWindowController; private CloudController cloudController; + private Stage primaryStage; private AnchorPane pane; private Scene scene; - private static String userHome = System.getProperty("user.home"); - private static String userName = System.getProperty("user.name"); - private static String osName = System.getProperty("os.name"); - private static String osArch = System.getProperty("os.arch"); - private static String osVers = System.getProperty("os.version"); - private static String javaVers = System.getProperty("java.version"); - private static String javaVend= System.getProperty("java.vendor"); - private String gamesDBdownloadURL = "https://git.mosad.xyz/Seil0/cemu_UI/raw/branch/master/downloadContent/games.db"; - private static String dirCemuUI; - private static File directory; - private static File configFile; - private static File gamesDBFile; - private static File reference_gamesFile; - private static File pictureCache; + private static Logger LOGGER; @Override public void start(Stage primaryStage) { try { - LOGGER.info("OS: " + osName + " " + osVers + " " + osArch); - LOGGER.info("Java: " + javaVend + " " + javaVers); - LOGGER.info("User: " + userName + " " + userHome); + LOGGER.info("OS: " + XMLController.getOsName() + " " + XMLController.getOsVers() + " " + XMLController.getOsVers()); + LOGGER.info("Java: " + XMLController.getJavaVend() + " " + XMLController.getJavaVers()); + LOGGER.info("User: " + XMLController.getUserName() + " " + XMLController.getUserHome()); this.primaryStage = primaryStage; - mainWindowController = new MainWindowController(this); + mainWindowController = new MainWindowController(); + main = this; mainWindow(); initActions(); @@ -94,11 +87,11 @@ public class Main extends Application { loader.setLocation(getClass().getResource("/fxml/MainWindow.fxml")); loader.setController(mainWindowController); pane = (AnchorPane) loader.load(); - primaryStage.setMinWidth(265.00); - primaryStage.setMinHeight(425.00); + primaryStage.setMinWidth(1130); + primaryStage.setMinHeight(600 + 34); primaryStage.setTitle("cemu_UI"); // primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream(""))); //adds application icon - primaryStage.setOnCloseRequest(event -> System.exit(1)); + primaryStage.setOnCloseRequest(event -> System.exit(0)); // generate window scene = new Scene(pane); // create new scene, append pane to scene @@ -106,51 +99,46 @@ public class Main extends Application { primaryStage.setScene(scene); // append scene to stage primaryStage.show(); // show stage - cloudController = new CloudController(mainWindowController); // call cloudController constructor + cloudController = CloudController.getInstance(mainWindowController); // call cloudController constructor // startup checks // check if client_secret.json is present if (Main.class.getResourceAsStream("/client_secret.json") == null) { LOGGER.error("client_secret is missing!!!!!"); - Alert alert = new Alert(AlertType.ERROR); - alert.setTitle("cemu_UI"); - alert.setHeaderText("Error"); - alert.setContentText("client_secret is missing! Please contact the maintainer. \nIf you compiled cemu_UI by yourself see: \nhttps://git.mosad.xyz/Seil0/cemu_UI/wiki/Documantation"); - alert.showAndWait(); + JFXInfoAlert noCSAlert = new JFXInfoAlert("Error", + "client_secret is missing! Please contact the maintainer. \n" + + "If you compiled cemu_UI by yourself see: \n" + + "https://git.mosad.xyz/Seil0/cemu_UI/wiki/Documantation", + "-fx-button-type: RAISED; -fx-background-color: #00a8cc; -fx-text-fill: BLACK;", primaryStage); + noCSAlert.showAndWait(); } - if (!directory.exists()) { + if (!XMLController.getDirCemuUI().exists()) { LOGGER.info("creating cemu_UI directory"); - directory.mkdir(); - pictureCache.mkdir(); + XMLController.getDirCemuUI().mkdir(); + XMLController.getPictureCache().mkdir(); } - if (!configFile.exists()) { + if (!XMLController.getConfigFile().exists()) { LOGGER.info("firststart, setting default values"); firstStart(); - mainWindowController.setColor("00a8cc"); - mainWindowController.setAutoUpdate(false); - mainWindowController.setLanguage("en_US"); - mainWindowController.setLastLocalSync(0); - mainWindowController.setxPosHelper(0); - mainWindowController.saveSettings(); + xmlController.saveSettings(); } - if (!pictureCache.exists()) { - pictureCache.mkdir(); + if (!XMLController.getPictureCache().exists()) { + XMLController.getPictureCache().mkdir(); } - - if (!reference_gamesFile.exists()) { - if (gamesDBFile.exists()) { - gamesDBFile.delete(); + if (!XMLController.getRference_gamesFile().exists()) { + if (XMLController.getGamesDBFile().exists()) { + XMLController.getGamesDBFile().delete(); } try { LOGGER.info("downloading ReferenceGameList.db... "); URL website = new URL(gamesDBdownloadURL); ReadableByteChannel rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(reference_gamesFile); + FileOutputStream fos = new FileOutputStream(XMLController.getRference_gamesFile()); fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); fos.close(); LOGGER.info("finished downloading games.db"); @@ -161,12 +149,11 @@ public class Main extends Application { // init here as it loads the games to the mwc and the gui, therefore the window must exist mainWindowController.init(); - mainWindowController.getDbController().init(); // if cloud sync is activated start sync - if(mainWindowController.isCloudSync()) { - cloudController.initializeConnection(mainWindowController.getCloudService(), mainWindowController.getCemuPath()); - cloudController.sync(mainWindowController.getCloudService(), mainWindowController.getCemuPath(), directory.getPath()); + if (XMLController.isCloudSync()) { + cloudController.initializeConnection(XMLController.getCloudService(), XMLController.getCemuPath()); + cloudController.sync(XMLController.getCloudService(), XMLController.getCemuPath(), XMLController.getDirCemuUIPath()); } } catch (IOException e) { @@ -175,56 +162,53 @@ public class Main extends Application { } public static void main(String[] args) { + String logPath = ""; - if (osName.contains("Windows")) { - dirCemuUI = userHome + "/Documents/cemu_UI"; + if (System.getProperty("os.name").contains("Windows")) { + logPath = System.getProperty("user.home") + "/Documents/cemu_UI/app.log"; } else { - dirCemuUI = userHome + "/cemu_UI"; + logPath = System.getProperty("user.home") + "/cemu_UI/app.log"; } - directory = new File(dirCemuUI); - configFile = new File(dirCemuUI + "/config.xml"); - gamesDBFile = new File(dirCemuUI + "/games.db"); - reference_gamesFile = new File(dirCemuUI + "/reference_games.db"); - pictureCache= new File(dirCemuUI+"/picture_cache"); - - // delete old log file and create new - System.setProperty("logFilename", dirCemuUI + "/app.log"); - File logFile = new File(dirCemuUI + "/app.log"); + System.setProperty("logFilename", logPath); + File logFile = new File(logPath); logFile.delete(); LOGGER = LogManager.getLogger(Main.class.getName()); + + xmlController = new XMLController(); launch(args); } private void firstStart() { - Alert alert = new Alert(AlertType.CONFIRMATION); // new alert with file-chooser - alert.setTitle("cemu_UI"); - alert.setHeaderText("cemu installation"); - alert.setContentText("please select your cemu installation"); - - Optional result = alert.showAndWait(); - if (result.get() == ButtonType.OK) { + + JFXOkayCancelAlert cemuInstallAlert = new JFXOkayCancelAlert("cemu installation", + "please select your cemu installation", + "-fx-button-type: RAISED; -fx-background-color: #00a8cc; -fx-text-fill: BLACK;", primaryStage); + cemuInstallAlert.setOkayAction(e -> { DirectoryChooser directoryChooser = new DirectoryChooser(); File selectedDirectory = directoryChooser.showDialog(primaryStage); - mainWindowController.setCemuPath(selectedDirectory.getAbsolutePath()); - - } else { - mainWindowController.setCemuPath(null); - } + XMLController.setCemuPath(selectedDirectory.getAbsolutePath()); + }); + cemuInstallAlert.setCancelAction(e -> { + XMLController.setCemuPath(null); + LOGGER.info("Action canceld by user!"); + }); + cemuInstallAlert.showAndWait(); - Alert alert2 = new Alert(AlertType.CONFIRMATION); // new alert with file-chooser - alert2.setTitle("cemu_UI"); - alert2.setHeaderText("rom directory"); - alert2.setContentText("please select your rom directory"); - - Optional result2 = alert2.showAndWait(); - if (result2.get() == ButtonType.OK) { + JFXOkayCancelAlert romDirectoryAlert = new JFXOkayCancelAlert("rom directory", + "please select your rom directory", + "-fx-button-type: RAISED; -fx-background-color: #00a8cc; -fx-text-fill: BLACK;", primaryStage); + romDirectoryAlert.setOkayAction(e -> { DirectoryChooser directoryChooser = new DirectoryChooser(); File selectedDirectory = directoryChooser.showDialog(primaryStage); - mainWindowController.setRomDirectoryPath(selectedDirectory.getAbsolutePath()); - } else { - mainWindowController.setRomDirectoryPath(null); - } + XMLController.setRomDirectoryPath(selectedDirectory.getAbsolutePath()); + }); + romDirectoryAlert.setCancelAction(e -> { + XMLController.setRomDirectoryPath(null); + LOGGER.info("Action canceld by user!"); + }); + romDirectoryAlert.showAndWait(); + } private void initActions() { @@ -236,12 +220,6 @@ public class Main extends Application { @Override public void changed(ObservableValue observable, Number oldValue, final Number newValue) { - int xPosHelperMax = (int) Math.floor((mainWindowController.getMainAnchorPane().getWidth() - 36) / 217); - - // call only if there is enough space for a new row - if (mainWindowController.getOldXPosHelper() != xPosHelperMax) { - mainWindowController.refreshUIData(); - } // if saveTask is already running kill it if (saveTask != null) saveTask.cancel(); @@ -249,7 +227,8 @@ public class Main extends Application { saveTask = new TimerTask() { @Override public void run() { - mainWindowController.saveSettings(); + XMLController.setWindowWidth(mainWindowController.getMainAnchorPane().getWidth()); + xmlController.saveSettings(); } }; timer.schedule(saveTask, delayTime); @@ -270,7 +249,8 @@ public class Main extends Application { saveTask = new TimerTask() { @Override public void run() { - mainWindowController.saveSettings(); + XMLController.setWindowHeight(mainWindowController.getMainAnchorPane().getHeight()); + xmlController.saveSettings(); } }; timer.schedule(saveTask, delayTime); @@ -299,48 +279,16 @@ public class Main extends Application { primaryStage.heightProperty().addListener(heightListener); primaryStage.maximizedProperty().addListener(maximizeListener); } - - public Stage getPrimaryStage() { - return primaryStage; - } - - public void setPrimaryStage(Stage primaryStage) { - this.primaryStage = primaryStage; + + public static Main getMain() { + return main; } public CloudController getCloudController() { return cloudController; } - public void setCloudController(CloudController cloudController) { - this.cloudController = cloudController; - } - public AnchorPane getPane() { return pane; } - - public void setPane(AnchorPane pane) { - this.pane = pane; - } - - public File getDirectory() { - return directory; - } - - public File getConfigFile() { - return configFile; - } - - public File getGamesDBFile() { - return gamesDBFile; - } - - public File getReference_gamesFile() { - return reference_gamesFile; - } - - public File getPictureCache() { - return pictureCache; - } } diff --git a/src/main/java/com/cemu_UI/application/MainWindowController.java b/src/main/java/com/cemu_UI/application/MainWindowController.java index 99e6640..c516faa 100644 --- a/src/main/java/com/cemu_UI/application/MainWindowController.java +++ b/src/main/java/com/cemu_UI/application/MainWindowController.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,23 +18,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.application; -import java.awt.Desktop; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.MalformedURLException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.sql.SQLException; @@ -53,16 +48,19 @@ import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.cemu_UI.controller.CloudController; import com.cemu_UI.controller.DBController; import com.cemu_UI.controller.SmmdbAPIController; import com.cemu_UI.controller.UpdateController; +import com.cemu_UI.controller.XMLController; import com.cemu_UI.datatypes.CourseTableDataType; +import com.cemu_UI.datatypes.GlobalDataTypes.CloudService; import com.cemu_UI.datatypes.SmmdbApiDataType; import com.cemu_UI.datatypes.UIROMDataType; -import com.cemu_UI.uiElements.JFXEditGameDialog; +import com.cemu_UI.uiElements.JFXEditGameAlert; import com.cemu_UI.uiElements.JFXInfoAlert; -import com.cemu_UI.uiElements.JFXOkayCancelDialog; -import com.cemu_UI.uiElements.JFXTextAreaInfoDialog; +import com.cemu_UI.uiElements.JFXOkayCancelAlert; +import com.cemu_UI.uiElements.JFXTextAreaAlert; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXColorPicker; import com.jfoenix.controls.JFXHamburger; @@ -82,7 +80,6 @@ import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.geometry.Insets; import javafx.scene.control.ChoiceBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; @@ -94,6 +91,7 @@ import javafx.scene.image.ImageView; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; @@ -103,172 +101,100 @@ import javafx.scene.text.FontWeight; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import javafx.stage.DirectoryChooser; +import javafx.stage.Stage; import javafx.util.Duration; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; public class MainWindowController { - @FXML - private JFXButton aboutBtn; - @FXML - private JFXButton settingsBtn; - @FXML - private JFXButton addBtn; - @FXML - private JFXButton reloadRomsBtn; - @FXML - private JFXButton smmdbBtn; - @FXML - private JFXButton cemuTFBtn; - @FXML - private JFXButton romTFBtn; - @FXML - private JFXButton updateBtn; - @FXML - private JFXButton smmdbDownloadBtn; - @FXML - private JFXButton playBtn; - @FXML - private JFXButton lastTimePlayedBtn; - @FXML - JFXButton totalPlaytimeBtn; + @FXML private JFXButton aboutBtn; + @FXML private JFXButton settingsBtn; + @FXML private JFXButton addBtn; + @FXML private JFXButton reloadRomsBtn; + @FXML private JFXButton smmdbBtn; + @FXML private JFXButton cemuTFBtn; + @FXML private JFXButton romTFBtn; + @FXML private JFXButton updateBtn; + @FXML private JFXButton smmdbDownloadBtn; + @FXML private JFXButton playBtn; + @FXML private JFXButton lastTimePlayedBtn; + @FXML JFXButton totalPlaytimeBtn; - @FXML - private JFXHamburger menuHam; + @FXML private JFXHamburger menuHam; - @FXML - private JFXTextField cemuTextField; - @FXML - private JFXTextField romTextField; - @FXML - private JFXTextField courseSearchTextFiled; - @FXML - private JFXTextField executeCommandTextFiled; + @FXML private JFXTextField cemuTextField; + @FXML private JFXTextField romTextField; + @FXML private JFXTextField courseSearchTextFiled; + @FXML private JFXTextField executeCommandTextFiled; - @FXML - private TextFlow smmdbTextFlow; + @FXML private TextFlow smmdbTextFlow; - @FXML - private JFXColorPicker colorPicker; + @FXML private JFXColorPicker colorPicker; - @FXML - private JFXToggleButton cloudSyncToggleBtn; - @FXML - private JFXToggleButton autoUpdateToggleBtn; - @FXML - private JFXToggleButton fullscreenToggleBtn; + @FXML private JFXToggleButton cloudSyncToggleBtn; + @FXML private JFXToggleButton autoUpdateToggleBtn; + @FXML private JFXToggleButton fullscreenToggleBtn; - @FXML - private ChoiceBox languageChoisBox; - @FXML - private ChoiceBox branchChoisBox; + @FXML private ChoiceBox languageChoisBox; + @FXML private ChoiceBox branchChoisBox; - @FXML - private AnchorPane mainAnchorPane; - @FXML - private AnchorPane gamesAnchorPane; - @FXML - private AnchorPane settingsAnchorPane; - @FXML - private AnchorPane smmdbAnchorPane; - - @FXML - private ScrollPane mainScrollPane; - @FXML - private ScrollPane settingsScrollPane; - @FXML - private ScrollPane smmdbScrollPane; - @FXML - private ScrollPane smmdbImageViewScrollPane; - - @FXML - private VBox sideMenuVBox; - - @FXML - private HBox topHBox; - @FXML - private HBox bottomHBox; - - @FXML - private ImageView smmdbImageView; - - @FXML - private Label helpLbl; - @FXML - private Label cemu_UISettingsLbl; - @FXML - private Label cemuDirectoryLbl; - @FXML - private Label romDirectoryLbl; - @FXML - private Label mainColorLbl; - @FXML - private Label languageLbl; - @FXML - private Label updateLbl; - @FXML - private Label branchLbl; - @FXML - private Label cemuSettingsLbl; - @FXML - private Label licensesLbl; - - @FXML - private JFXTreeTableView courseTreeTable = new JFXTreeTableView(); - - @FXML - private TreeItem root = new TreeItem<>(new CourseTableDataType("", "", 0, 0)); - - @FXML - private JFXTreeTableColumn titleColumn = new JFXTreeTableColumn<>("title"); - @FXML - private JFXTreeTableColumn idColumn = new JFXTreeTableColumn<>("id"); - @FXML - private JFXTreeTableColumn starsColumn = new JFXTreeTableColumn<>("stars"); - @FXML - private JFXTreeTableColumn timeColumn = new JFXTreeTableColumn<>("time"); + @FXML private ScrollPane mainScrollPane; + @FXML private ScrollPane settingsScrollPane; + @FXML private ScrollPane smmdbScrollPane; + @FXML private ScrollPane smmdbImageViewScrollPane; - @SuppressWarnings("unused") - private enum CloudService { - GoogleDrive, Dropbox - } + @FXML private AnchorPane mainAnchorPane; + @FXML private AnchorPane settingsAnchorPane; + @FXML private AnchorPane smmdbAnchorPane; + + @FXML private FlowPane gamesFlowPane; + + @FXML private VBox sideMenuVBox; + + @FXML private HBox topHBox; + @FXML private HBox bottomHBox; + + @FXML private ImageView smmdbImageView; + + @FXML private Label helpLbl; + @FXML private Label cemu_UISettingsLbl; + @FXML private Label cemuDirectoryLbl; + @FXML private Label romDirectoryLbl; + @FXML private Label mainColorLbl; + @FXML private Label languageLbl; + @FXML private Label updateLbl; + @FXML private Label branchLbl; + @FXML private Label cemuSettingsLbl; + @FXML private Label licensesLbl; + + @FXML private JFXTreeTableView courseTreeTable = new JFXTreeTableView(); + + @FXML private TreeItem root = new TreeItem<>(new CourseTableDataType("", "", 0, 0)); + + @FXML private JFXTreeTableColumn titleColumn = new JFXTreeTableColumn<>("title"); + @FXML private JFXTreeTableColumn idColumn = new JFXTreeTableColumn<>("id"); + @FXML private JFXTreeTableColumn starsColumn = new JFXTreeTableColumn<>("stars"); + @FXML private JFXTreeTableColumn timeColumn = new JFXTreeTableColumn<>("time"); - private Main main; - private DBController dbController; - private SmmdbAPIController smmdbAPIController; - private playGame playGame; private static MainWindowController MWC; - private UpdateController updateController; + private XMLController xmlController; + private DBController dbController; + private playGame playGame; + private SmmdbAPIController smmdbAPIController; + private Stage primaryStage; private boolean menuTrue = false; - private boolean settingsTrue = false; private boolean playTrue = false; - private boolean smmdbTrue = false; - private boolean autoUpdate = false; - private boolean useBeta = false; - private boolean fullscreen; - private boolean cloudSync; - private String cloudService = ""; // set cloud provider (at the moment only GoogleDrive, Dropbox is planed) - private String cemuPath; - private String romDirectoryPath; private String gameExecutePath; - private String color; - private String dialogBtnStyle; + private String btnStyle; private String selectedGameTitleID; private String selectedGameTitle; private String id; - private String version = "0.3.1"; - private String buildNumber = "081"; + private String version = "0.3.3"; + private String buildNumber = "089"; private String versionName = "Purple Comet"; - private int xPos = -200; - private int yPos = 17; - private int xPosHelper; - private int oldXPosHelper; private int selectedUIDataIndex; private int selected; - private long lastLocalSync; - private double windowWidth; - private double windowHeight; private DirectoryChooser directoryChooser = new DirectoryChooser(); private ObservableList branches = FXCollections.observableArrayList("stable", "beta"); private ObservableList languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)"); @@ -288,57 +214,16 @@ public class MainWindowController { private MenuItem addDLC = new MenuItem("add DLC"); private ContextMenu gameContextMenu = new ContextMenu(edit, remove, addUpdate, addDLC); private Label lastGameLabel = new Label(); - - private ImageView add_circle_black = new ImageView(new Image("icons/ic_add_circle_black_24dp_1x.png")); - private ImageView info_black = new ImageView(new Image("icons/ic_info_black_24dp_1x.png")); - private ImageView settings_black = new ImageView(new Image("icons/ic_settings_black_24dp_1x.png")); - private ImageView cached_black = new ImageView(new Image("icons/ic_cached_black_24dp_1x.png")); - private ImageView smmdb_black = new ImageView(new Image("icons/ic_get_app_black_24dp_1x.png")); - private ImageView add_circle_white = new ImageView(new Image("icons/ic_add_circle_white_24dp_1x.png")); - private ImageView info_white = new ImageView(new Image("icons/ic_info_white_24dp_1x.png")); - private ImageView settings_white = new ImageView(new Image("icons/ic_settings_white_24dp_1x.png")); - private ImageView cached_white = new ImageView(new Image("icons/ic_cached_white_24dp_1x.png")); - private ImageView smmdb_white = new ImageView(new Image("icons/ic_get_app_white_24dp_1x.png")); - private Image close_black = new Image("icons/close_black_2048x2048.png"); // language support - private ResourceBundle bundle; - private String language; - private String editHeadingText; - private String editBodyText; - private String removeHeadingText; - private String removeBodyText; - private String addUpdateHeadingText; - private String addUpdateBodyText; - private String addDLCHeadingText; - private String addDLCBodyText; - private String licensesLblHeadingText; - private String licensesLblBodyText; - private String showLicenses; - private String aboutBtnHeadingText; - private String aboutBtnBodyText; - private String cloudSyncWaringHeadingText; - private String cloudSyncWaringBodyText; - private String cloudSyncErrorHeadingText; - private String cloudSyncErrorBodyText; - private String addGameBtnHeadingText; - private String addGameBtnBodyText; - private String addBtnReturnErrorHeadingText; - private String addBtnReturnErrorBodyText; private String lastPlayed; private String today; private String yesterday; private String never; - private String playBtnPlay; - private String playBtnUpdating; - private String playBtnCopyingFiles; - private String smmdbDownloadBtnLoading; - private String smmdbDownloadBtnDownload; - - public MainWindowController(Main main) { - this.main = main; - dbController = new DBController(main, this); + public MainWindowController() { + xmlController = new XMLController(); + dbController = DBController.getInstance(); smmdbAPIController = new SmmdbAPIController(); } @@ -347,10 +232,15 @@ public class MainWindowController { * loadSettings, checkAutoUpdate, initUI and initActions */ public void init() { - loadSettings(); + xmlController.loadSettings(); // load settings checkAutoUpdate(); initUI(); initActions(); + + dbController.init(); + dbController.refreshDataBase(); + games = dbController.loadAllGames(); + addAllGames(); } /** @@ -359,21 +249,24 @@ public class MainWindowController { private void initUI() { LOGGER.info("initializing UI ..."); - if (getWindowWidth() > 100 && getWindowHeight() > 100) { - mainAnchorPane.setPrefSize(getWindowWidth(), getWindowHeight()); + primaryStage = (Stage) mainAnchorPane.getScene().getWindow(); // set primary stage for dialogs + + // TODO this is broken + if (XMLController.getWindowWidth() > 100 && XMLController.getWindowHeight() > 100) { + mainAnchorPane.setPrefSize(XMLController.getWindowWidth(), XMLController.getWindowHeight()); } - cemuTextField.setText(cemuPath); - romTextField.setText(romDirectoryPath); - colorPicker.setValue(Color.valueOf(getColor())); - fullscreenToggleBtn.setSelected(isFullscreen()); - cloudSyncToggleBtn.setSelected(isCloudSync()); - autoUpdateToggleBtn.setSelected(isAutoUpdate()); + cemuTextField.setText(XMLController.getCemuPath()); + romTextField.setText(XMLController.getRomDirectoryPath()); + colorPicker.setValue(Color.valueOf(XMLController.getColor())); + fullscreenToggleBtn.setSelected(XMLController.isFullscreen()); + cloudSyncToggleBtn.setSelected(XMLController.isCloudSync()); + autoUpdateToggleBtn.setSelected(XMLController.isAutoUpdate()); branchChoisBox.setItems(branches); languageChoisBox.setItems(languages); bottomHBox.setPickOnBounds(false); - if (isUseBeta()) { + if (XMLController.isUseBeta()) { branchChoisBox.getSelectionModel().select(1); } else { branchChoisBox.getSelectionModel().select(0); @@ -418,6 +311,7 @@ public class MainWindowController { if (playTrue) { playBtnSlideOut(); } + if (menuTrue) { sideMenuSlideOut(); burgerTask.setRate(-1.0); @@ -429,91 +323,74 @@ public class MainWindowController { burgerTask.play(); menuTrue = true; } - if (settingsTrue) { + + if (settingsScrollPane.isVisible()) { settingsScrollPane.setVisible(false); - saveSettings(); - settingsTrue = false; - } - if (smmdbTrue) { - smmdbAnchorPane.setVisible(false); - smmdbTrue = false; + xmlController.saveSettings(); } - }); - - edit.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - try { - LOGGER.info("edit " + selectedGameTitleID); - String[] gameInfo = dbController.getGameInfo(selectedGameTitleID); - - // new edit dialog - String headingText = editHeadingText + " \"" + selectedGameTitle + "\""; - JFXEditGameDialog editGameDialog = new JFXEditGameDialog(headingText, editBodyText, dialogBtnStyle, 450, - 300, 1, MWC, main.getPrimaryStage(), main.getPane()); - editGameDialog.setTitle(gameInfo[0]); - editGameDialog.setCoverPath(gameInfo[1]); - editGameDialog.setRomPath(gameInfo[2]); - editGameDialog.setTitleID(gameInfo[3]); - editGameDialog.show(); - } catch (Exception e) { - LOGGER.warn("trying to edit " + selectedGameTitleID + ",which is not a valid type!", e); - } + if (smmdbAnchorPane.isVisible()) { + smmdbAnchorPane.setVisible(false); } }); - remove.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - try { - LOGGER.info("remove " + selectedGameTitle + "(" + selectedGameTitleID + ")"); - String headingText = removeHeadingText + " \"" + selectedGameTitle + "\""; - String bodyText = removeBodyText + " " + selectedGameTitle + " ?"; - EventHandler okayAction = new EventHandler() { - @Override - public void handle(ActionEvent event) { - try { - games.remove(selectedUIDataIndex); // remove game form games-list - dbController.removeGame(selectedGameTitleID); // remove game from database - refreshUIData(); // refresh all games at gamesAnchorPane (UI) - } catch (Exception e) { - LOGGER.error("error while removing ROM from database!", e); - } - } - }; + edit.setOnAction(event -> { + try { + LOGGER.info("edit " + selectedGameTitleID); + String[] gameInfo = dbController.getGameInfo(selectedGameTitleID); - EventHandler cancelAction = new EventHandler() { - @Override - public void handle(ActionEvent event) { - LOGGER.info("Action canceld by user!"); - } - }; - - JFXOkayCancelDialog removeGameDialog = new JFXOkayCancelDialog(headingText, bodyText, - dialogBtnStyle, 350, 170, okayAction, cancelAction, main.getPane(), bundle); - removeGameDialog.show(); - } catch (Exception e) { - LOGGER.error("error while removing " + selectedGameTitle + "(" + selectedGameTitleID + ")", e); - } - } + // new edit dialog + String headingText = XMLController.getLocalBundle().getString("editHeadingText") + " \"" + selectedGameTitle + "\""; + JFXEditGameAlert editGameAlert = new JFXEditGameAlert(headingText, + XMLController.getLocalBundle().getString("editBodyText"), btnStyle, 1, primaryStage, MWC); + editGameAlert.setTitle(gameInfo[0]); + editGameAlert.setCoverPath(gameInfo[1]); + editGameAlert.setRomPath(gameInfo[2]); + editGameAlert.setTitleID(gameInfo[3]); + editGameAlert.showAndWait(); + } catch (Exception e) { + LOGGER.warn("trying to edit " + selectedGameTitleID + ",which is not a valid type!", e); + } }); + remove.setOnAction(event -> { + try { + LOGGER.info("remove " + selectedGameTitle + "(" + selectedGameTitleID + ")"); + String headingText = XMLController.getLocalBundle().getString("removeHeadingText") + " \"" + selectedGameTitle + "\""; + String bodyText = XMLController.getLocalBundle().getString("removeBodyText") + " " + selectedGameTitle + " ?"; + JFXOkayCancelAlert removeGameAlert = new JFXOkayCancelAlert(headingText, bodyText, btnStyle, + primaryStage); + removeGameAlert.setOkayAction(e -> { + try { + games.remove(selectedUIDataIndex); // remove game form games-list + dbController.removeGame(selectedGameTitleID); // remove game from database + refreshUIData(); // refresh all games at gamesAnchorPane (UI) + } catch (Exception ex) { + LOGGER.error("error while removing ROM from database!", ex); + } + }); + removeGameAlert.setCancelAction(e -> LOGGER.info("Action canceld by user!")); + removeGameAlert.showAndWait(); + } catch (Exception e) { + LOGGER.error("error while removing " + selectedGameTitle + "(" + selectedGameTitleID + ")", e); + } + }); + addUpdate.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { try { LOGGER.info("update: " + selectedGameTitleID); - String headingText = addUpdateHeadingText + " \"" + selectedGameTitle + "\""; + EventHandler okayAction = new EventHandler() { @Override public void handle(ActionEvent event) { DirectoryChooser directoryChooser = new DirectoryChooser(); - File selectedDirecroty = directoryChooser.showDialog(main.getPrimaryStage()); + File selectedDirecroty = directoryChooser.showDialog(primaryStage); String updatePath = selectedDirecroty.getAbsolutePath(); String[] parts = selectedGameTitleID.split("-"); // split string into 2 parts at "-" File srcDir = new File(updatePath); - File destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1]); + File destDir = new File(XMLController.getCemuPath() + "/mlc01/usr/title/" + parts[0] + "/" + parts[1]); // if directory doesn't exist create it if (destDir.exists() != true) { @@ -522,10 +399,10 @@ public class MainWindowController { try { LOGGER.info("copying the content of " + updatePath + " to " + destDir.toString()); - playBtn.setText(playBtnUpdating); + playBtn.setText(XMLController.getLocalBundle().getString("playBtnUpdating")); playBtn.setDisable(true); FileUtils.copyDirectory(srcDir, destDir); - playBtn.setText(playBtnPlay); + playBtn.setText(XMLController.getLocalBundle().getString("playBtnPlay")); playBtn.setDisable(false); LOGGER.info("copying files done!"); } catch (IOException e) { @@ -541,9 +418,12 @@ public class MainWindowController { } }; - JFXOkayCancelDialog updateGameDialog = new JFXOkayCancelDialog(headingText, addUpdateBodyText, - dialogBtnStyle, 350, 170, okayAction, cancelAction, main.getPane(), bundle); - updateGameDialog.show(); + String headingText = XMLController.getLocalBundle().getString("addUpdateHeadingText") + " \"" + selectedGameTitle + "\""; + JFXOkayCancelAlert updateGameAlert = new JFXOkayCancelAlert(headingText, + XMLController.getLocalBundle().getString("addUpdateBodyText"), btnStyle, primaryStage); + updateGameAlert.setOkayAction(okayAction); + updateGameAlert.setCancelAction(cancelAction); + updateGameAlert.showAndWait(); } catch (Exception e) { LOGGER.warn("trying to update " + selectedGameTitleID + ",which is not a valid type!", e); } @@ -555,16 +435,16 @@ public class MainWindowController { public void handle(ActionEvent event) { try { LOGGER.info("add DLC: " + selectedGameTitleID); - String headingText = addDLCHeadingText + " \"" + selectedGameTitle + "\""; + String headingText = XMLController.getLocalBundle().getString("addDLCHeadingText") + " \"" + selectedGameTitle + "\""; EventHandler okayAction = new EventHandler() { @Override public void handle(ActionEvent event) { DirectoryChooser directoryChooser = new DirectoryChooser(); - File selectedDirecroty = directoryChooser.showDialog(main.getPrimaryStage()); + File selectedDirecroty = directoryChooser.showDialog(primaryStage); String dlcPath = selectedDirecroty.getAbsolutePath(); String[] parts = selectedGameTitleID.split("-"); // split string into 2 parts at "-" File srcDir = new File(dlcPath); - File destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1] + "/aoc"); + File destDir = new File(XMLController.getCemuPath() + "/mlc01/usr/title/" + parts[0] + "/" + parts[1] + "/aoc"); // if directory doesn't exist create it if (destDir.exists() != true) { @@ -573,10 +453,10 @@ public class MainWindowController { try { LOGGER.info("copying the content of " + dlcPath + " to " + destDir.toString()); - playBtn.setText(playBtnCopyingFiles); + playBtn.setText(XMLController.getLocalBundle().getString("playBtnCopyingFiles")); playBtn.setDisable(true); FileUtils.copyDirectory(srcDir, destDir); - playBtn.setText(playBtnPlay); + playBtn.setText(XMLController.getLocalBundle().getString("playBtnPlay")); playBtn.setDisable(false); LOGGER.info("copying files done!"); } catch (IOException e) { @@ -591,17 +471,19 @@ public class MainWindowController { LOGGER.info("Action canceld by user!"); } }; - - JFXOkayCancelDialog addDLCDialog = new JFXOkayCancelDialog(headingText, addDLCBodyText, dialogBtnStyle, - 350, 170, okayAction, cancelAction, main.getPane(), bundle); - addDLCDialog.show(); + + JFXOkayCancelAlert addDLCAlert = new JFXOkayCancelAlert(headingText, + XMLController.getLocalBundle().getString("addDLCBodyText"), btnStyle, primaryStage); + addDLCAlert.setOkayAction(okayAction); + addDLCAlert.setCancelAction(cancelAction); + addDLCAlert.showAndWait(); } catch (Exception e) { LOGGER.warn("trying to add a dlc to " + selectedGameTitleID + ",which is not a valid type!", e); } } }); - gamesAnchorPane.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler() { + gamesFlowPane.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { if (playTrue) { @@ -627,9 +509,7 @@ public class MainWindowController { root.getChildren().remove(0, root.getChildren().size()); for (int i = 0; i < courses.size(); i++) { - if (courses.get(i).getTitle().toLowerCase() - .contains(courseSearchTextFiled.getText().toLowerCase())) { - + if (courses.get(i).getTitle().toLowerCase().contains(courseSearchTextFiled.getText().toLowerCase())) { // add data from courses to filteredCourses where title contains search input filteredCourses.add(courses.get(i)); } @@ -669,7 +549,7 @@ public class MainWindowController { smmdbImageView.setImage(scaledImage); // set imageview to image } catch (MalformedURLException | URISyntaxException e) { LOGGER.warn("There was either a problem or no image!", e); - smmdbImageView.setImage(close_black); + smmdbImageView.setImage(new Image("icons/close_black_2048x2048.png")); } addCourseDescription(courses.get(i)); } @@ -677,123 +557,86 @@ public class MainWindowController { } }); - helpLbl.setOnMouseClicked(new EventHandler() { - @Override - public void handle(MouseEvent mouseEvent) { - if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) { - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - try { - Desktop.getDesktop().browse(new URI("https://git.mosad.xyz/Seil0/cemu_UI/issues/3")); - } catch (IOException | URISyntaxException e) { - LOGGER.error("An error ocoured while trying to open a Website.", e); - } - } - }); - thread.start(); - } + helpLbl.setOnMouseClicked(event -> { + if (event.getButton().equals(MouseButton.PRIMARY)) { + Main.getMain().getHostServices().showDocument("https://git.mosad.xyz/Seil0/cemu_UI/issues/3"); } }); - languageChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number value, Number new_value) { - String language = languageChoisBox.getItems().get((int) new_value).toString(); - language = language.substring(language.length()-6,language.length()-1); //reading only en_US from English (en_US) - setLanguage(language); - setUILanguage(); - saveSettings(); - } - }); + languageChoisBox.getSelectionModel().selectedIndexProperty().addListener((event, oldValue, newValue) -> { + String language = languageChoisBox.getItems().get((int) newValue).toString(); + language = language.substring(language.length() - 6, language.length() - 1); // reading only en_US from + // English (en_US) + XMLController.setUsrLocal(language); + setUILanguage(); + xmlController.saveSettings(); + }); - branchChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number value, Number new_value) { - if (branchChoisBox.getItems().get((int) new_value).toString() == "beta") { - setUseBeta(true); - } else { - setUseBeta(false); - } - saveSettings(); + branchChoisBox.getSelectionModel().selectedIndexProperty().addListener((e, oldValue, newValue) -> { + if (branchChoisBox.getItems().get((int) newValue).toString() == "beta") { + XMLController.setUseBeta(true); + } else { + XMLController.setUseBeta(false); + } + xmlController.saveSettings(); + }); + + licensesLbl.setOnMouseClicked(event -> { + if (event.getButton().equals(MouseButton.PRIMARY)) { + + EventHandler cancelAction = cE -> { + String textAreaText = ""; + + try { + BufferedReader licenseBR = new BufferedReader( + new InputStreamReader(getClass().getResourceAsStream("/licenses/licenses_show.txt"))); + String currentLine; + + while ((currentLine = licenseBR.readLine()) != null) { + textAreaText = textAreaText + currentLine + "\n"; + } + + licenseBR.close(); + } catch (IOException ex) { + LOGGER.error("Cloud not read the license file!", ex); + } + + JFXTextAreaAlert licenseAlert = new JFXTextAreaAlert("cemu_UI", textAreaText, btnStyle, primaryStage); + licenseAlert.showAndWait(); + }; + + JFXOkayCancelAlert licenseOverviewAlert = new JFXOkayCancelAlert( + XMLController.getLocalBundle().getString("licensesLblHeadingText"), + XMLController.getLocalBundle().getString("licensesLblBodyText"), btnStyle, primaryStage); + licenseOverviewAlert.setOkayAction(oE -> {}); + licenseOverviewAlert.setCancelAction(cancelAction); + licenseOverviewAlert.setCancelText(XMLController.getLocalBundle().getString("showLicenses")); + licenseOverviewAlert.showAndWait(); } }); - licensesLbl.setOnMouseClicked(new EventHandler() { - @Override - public void handle(MouseEvent mouseEvent) { - if(mouseEvent.getButton().equals(MouseButton.PRIMARY)){ - - EventHandler okayAction = new EventHandler() { - @Override - public void handle(ActionEvent event) { - // do nothing - } - }; - EventHandler cancelAction = new EventHandler() { - @Override - public void handle(ActionEvent event) { - String headingText = "cemu_UI"; - String bodyText = ""; - - try { - BufferedReader licenseBR = new BufferedReader( - new InputStreamReader(getClass().getResourceAsStream("/licenses/licenses_show.txt"))); - String currentLine; - - while ((currentLine = licenseBR.readLine()) != null) { - bodyText = bodyText + currentLine + "\n"; - } - - licenseBR.close(); - } catch (IOException e) { - LOGGER.error("Cloud not read the license file!", e); - } - - JFXTextAreaInfoDialog licenseDialog = new JFXTextAreaInfoDialog(headingText, bodyText, - dialogBtnStyle, 510, 450, main.getPane()); - licenseDialog.show(); - licenseDialog.getTextArea().setEditable(false); - } - }; - - JFXOkayCancelDialog licenseOverviewDialog = new JFXOkayCancelDialog(licensesLblHeadingText, - licensesLblBodyText, dialogBtnStyle, 350, 275, okayAction, cancelAction, main.getPane(), - bundle); - licenseOverviewDialog.setCancelText(showLicenses); - licenseOverviewDialog.show(); - } - } - }); - - cemuTextField.textProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) { - if (new File(newValue).exists()) { - setCemuPath(newValue); - saveSettings(); - } else { - String bodyText = newValue + ": No such file or directory"; - JFXInfoAlert fileErrorDialog = new JFXInfoAlert("Waring!", bodyText, dialogBtnStyle, main.getPrimaryStage()); - fileErrorDialog.showAndWait(); - LOGGER.warn(newValue + ": No such file or directory"); - } + cemuTextField.textProperty().addListener((e, oldValue, newValue) -> { + if (new File(newValue).exists()) { + XMLController.setCemuPath(newValue); + xmlController.saveSettings(); + } else { + String bodyText = newValue + ": No such file or directory"; + JFXInfoAlert fileErrorDialog = new JFXInfoAlert("Waring!", bodyText, btnStyle, primaryStage); + fileErrorDialog.showAndWait(); + LOGGER.warn(newValue + ": No such file or directory"); } }); - romTextField.textProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) { - if (new File(newValue).exists()) { - setRomDirectoryPath(newValue); - saveSettings(); - reloadRoms(); - } else { - String bodyText = newValue + ": No such file or directory"; - JFXInfoAlert fileErrorDialog = new JFXInfoAlert("Waring!", bodyText, dialogBtnStyle, main.getPrimaryStage()); - fileErrorDialog.showAndWait(); - LOGGER.warn(newValue + ": No such file or directory"); - } + romTextField.textProperty().addListener((e, oldValue, newValue) -> { + if (new File(newValue).exists()) { + XMLController.setRomDirectoryPath(newValue); + xmlController.saveSettings(); + reloadRoms(); + } else { + String bodyText = newValue + ": No such file or directory"; + JFXInfoAlert fileErrorDialog = new JFXInfoAlert("Waring!", bodyText, btnStyle, primaryStage); + fileErrorDialog.showAndWait(); + LOGGER.warn(newValue + ": No such file or directory"); } }); @@ -807,27 +650,21 @@ public class MainWindowController { @FXML private void aboutBtnAction() { - String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (" + buildNumber + ") \"" + versionName + "\" \n" - + aboutBtnBodyText; - - JFXInfoAlert infoAlert = new JFXInfoAlert(aboutBtnHeadingText, bodyText, dialogBtnStyle, main.getPrimaryStage()); + String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (" + buildNumber + ") \"" + versionName + + "\" \n" + XMLController.getLocalBundle().getString("aboutBtnBodyText"); + + JFXInfoAlert infoAlert = new JFXInfoAlert(XMLController.getLocalBundle().getString("aboutBtnHeadingText"), + bodyText, btnStyle, primaryStage); infoAlert.showAndWait(); } @FXML private void settingsBtnAction() { - if (smmdbTrue) { + if (smmdbAnchorPane.isVisible()) { smmdbAnchorPane.setVisible(false); - smmdbTrue = false; - } - if (settingsTrue) { - settingsScrollPane.setVisible(false); - settingsTrue = false; - saveSettings(); - } else { - settingsScrollPane.setVisible(true); - settingsTrue = true; } + settingsScrollPane.setVisible(!settingsScrollPane.isVisible()); + xmlController.saveSettings(); // saving settings to be sureMouseEvent.MOUSE_CLICKED, (event) -> { } @FXML @@ -838,19 +675,15 @@ public class MainWindowController { @FXML private void smmdbBtnAction() { // show smmdbAnchorPane - if (smmdbTrue) { - smmdbAnchorPane.setVisible(false); - smmdbTrue = false; - } else { - smmdbAnchorPane.setVisible(true); - smmdbTrue = true; - + smmdbAnchorPane.setVisible(!smmdbAnchorPane.isVisible()); + + if (smmdbAnchorPane.isVisible()) { // start query in new thread Thread thread = new Thread(new Runnable() { @Override public void run() { Platform.runLater(() -> { - smmdbDownloadBtn.setText(smmdbDownloadBtnLoading); + smmdbDownloadBtn.setText(XMLController.getLocalBundle().getString("smmdbDownloadBtnLoading")); smmdbDownloadBtn.setDisable(true); root.getChildren().remove(0,root.getChildren().size()); }); @@ -864,7 +697,7 @@ public class MainWindowController { Platform.runLater(() -> { root.getChildren().add(new TreeItem(helpCourse)); // add data to root-node - smmdbDownloadBtn.setText(smmdbDownloadBtnDownload); + smmdbDownloadBtn.setText(XMLController.getLocalBundle().getString("smmdbDownloadBtnDownload")); smmdbDownloadBtn.setDisable(false); }); } @@ -894,7 +727,7 @@ public class MainWindowController { @FXML private void cemuTFBtnAction() { - File cemuDirectory = directoryChooser.showDialog(main.getPrimaryStage()); + File cemuDirectory = directoryChooser.showDialog(primaryStage); if (cemuDirectory != null) { cemuTextField.setText(cemuDirectory.getAbsolutePath()); } @@ -902,7 +735,7 @@ public class MainWindowController { @FXML private void romTFBtnAction() { - File romDirectory = directoryChooser.showDialog(main.getPrimaryStage()); + File romDirectory = directoryChooser.showDialog(primaryStage); if (romDirectory != null) { romTextField.setText(romDirectory.getAbsolutePath()); } @@ -910,7 +743,7 @@ public class MainWindowController { @FXML private void updateBtnAction() { - updateController = new UpdateController(this, buildNumber, useBeta); + UpdateController updateController = new UpdateController(this, buildNumber, XMLController.isUseBeta()); Thread updateThread = new Thread(updateController); updateThread.setName("Updater"); updateThread.start(); @@ -918,12 +751,8 @@ public class MainWindowController { @FXML private void autoUpdateToggleBtnAction() { - if (isAutoUpdate()) { - setAutoUpdate(false); - } else { - setAutoUpdate(true); - } - saveSettings(); + XMLController.setAutoUpdate(!XMLController.isAutoUpdate()); + xmlController.saveSettings(); } @FXML @@ -934,8 +763,8 @@ public class MainWindowController { @FXML private void smmdbDownloadBtnAction() { String downloadUrl = "http://smmdb.ddns.net/api/downloadcourse?id=" + id + "&type=zip"; - String downloadFileURL = getCemuPath() + "/" + id + ".zip"; // getCemuPath() + "/" + smmID + "/" + id + ".rar" - String outputFile = getCemuPath() + "/"; + String downloadFileURL = XMLController.getCemuPath() + "/" + id + ".zip"; // getCemuPath() + "/" + smmID + "/" + id + ".rar" + String outputFile = XMLController.getCemuPath() + "/"; try { LOGGER.info("beginning download ..."); @@ -1001,62 +830,49 @@ public class MainWindowController { @FXML private void fullscreenToggleBtnAction() { - if (fullscreen) { - fullscreen = false; - } else { - fullscreen = true; - } - saveSettings(); + XMLController.setFullscreen(!XMLController.isFullscreen()); + xmlController.saveSettings(); } @FXML private void cloudSyncToggleBtnAction() { - if(cloudSync) { - cloudSync = false; - } else { - EventHandler okayAction = new EventHandler(){ - @Override - public void handle(ActionEvent event){ - cloudSync = true; - //TODO rework for other cloud services -// CloudService service = CloudService.GoogleDrive; - cloudService = "GoogleDrive"; - - // start cloud sync in new thread - Thread thread = new Thread(new Runnable() { - @Override - public void run() { + XMLController.setCloudSync(!XMLController.isCloudSync()); - if (main.getCloudController().initializeConnection(getCloudService(), getCemuPath())) { - main.getCloudController().sync(getCloudService(), getCemuPath(), main.getDirectory().getPath()); - saveSettings(); - } else { - cloudSyncToggleBtn.setSelected(false); + if (XMLController.isCloudSync()) { + EventHandler okayAction = e -> { + // TODO rework for other cloud services +// CloudService service = CloudService.GoogleDrive; + XMLController.setCloudService(CloudService.GoogleDrive); - // cloud sync init error dialog - JFXInfoAlert cloudSyncErrorDialog = new JFXInfoAlert(cloudSyncErrorHeadingText, - cloudSyncErrorBodyText, dialogBtnStyle, main.getPrimaryStage()); - cloudSyncErrorDialog.showAndWait(); - } + // start cloud sync in new thread + Runnable task = () -> { + if (CloudController.getInstance(MWC).initializeConnection(XMLController.getCloudService(), + XMLController.getCemuPath())) { + CloudController.getInstance(MWC).sync(XMLController.getCloudService(), + XMLController.getCemuPath(), XMLController.getDirCemuUIPath()); + xmlController.saveSettings(); + } else { + cloudSyncToggleBtn.setSelected(false); - } - }); - thread.start(); - } - }; - - EventHandler cancelAction = new EventHandler(){ - @Override - public void handle(ActionEvent event){ - cloudSyncToggleBtn.setSelected(false); - } - }; - - JFXOkayCancelDialog cloudSyncWarningDialog = new JFXOkayCancelDialog(cloudSyncWaringHeadingText, - cloudSyncWaringBodyText, dialogBtnStyle, 419, 140, okayAction, cancelAction, main.getPane(), - bundle); - cloudSyncWarningDialog.show(); - } + // cloud sync init error dialog + JFXInfoAlert cloudSyncErrorDialog = new JFXInfoAlert( + XMLController.getLocalBundle().getString("cloudSyncErrorHeadingText"), + XMLController.getLocalBundle().getString("cloudSyncErrorBodyText"), btnStyle, + primaryStage); + cloudSyncErrorDialog.showAndWait(); + } + }; + + new Thread(task).start(); + }; + + JFXOkayCancelAlert cloudSyncWarningAlert = new JFXOkayCancelAlert( + XMLController.getLocalBundle().getString("cloudSyncWaringHeadingText"), + XMLController.getLocalBundle().getString("cloudSyncWaringHeadingText"), btnStyle, primaryStage); + cloudSyncWarningAlert.setOkayAction(okayAction); + cloudSyncWarningAlert.setCancelAction(e -> cloudSyncToggleBtn.setSelected(false)); + cloudSyncWarningAlert.showAndWait(); + } } @FXML @@ -1067,11 +883,10 @@ public class MainWindowController { @FXML private void addBtnAction() { - String headingText = addGameBtnHeadingText; - String bodyText = addGameBtnBodyText; - JFXEditGameDialog addGameDialog = new JFXEditGameDialog(headingText, bodyText, dialogBtnStyle, 450, 300, 0, - this, main.getPrimaryStage(), main.getPane()); - addGameDialog.show(); + JFXEditGameAlert addGameAlert = new JFXEditGameAlert( + XMLController.getLocalBundle().getString("addGameBtnHeadingText"), + XMLController.getLocalBundle().getString("addGameBtnBodyText"), btnStyle, 0, primaryStage, MWC); + addGameAlert.showAndWait(); } /** @@ -1087,13 +902,14 @@ public class MainWindowController { if (romPath.length() == 0 || coverPath.length() == 0 || title.length() == 0 || titleID.length() == 0) { LOGGER.info("No parameter set!"); - //addGame error dialog - JFXInfoAlert errorDialog = new JFXInfoAlert(addBtnReturnErrorHeadingText, addBtnReturnErrorBodyText, - dialogBtnStyle, main.getPrimaryStage()); - errorDialog.showAndWait(); + // addGame error dialog + JFXInfoAlert errorAlert = new JFXInfoAlert( + XMLController.getLocalBundle().getString("addBtnReturnErrorHeadingText"), + XMLController.getLocalBundle().getString("addBtnReturnErrorBodyText"), btnStyle, primaryStage); + errorAlert.showAndWait(); } else { - File pictureCache = main.getPictureCache(); + File pictureCache = XMLController.getPictureCache(); String coverName = new File(coverPath).getName(); try { BufferedImage originalImage = ImageIO.read(new File(coverPath)); //load cover @@ -1107,7 +923,8 @@ public class MainWindowController { try { dbController.addGame(title, coverPath, romPath, titleID, "", "", "", "0"); - dbController.loadSingleGame(titleID); + games.add(dbController.loadSingleGame(titleID)); + addGame(games.stream().filter(x -> x.getRomPath().equals(romPath)).findFirst().orElse(null)); if (menuTrue) { sideMenuSlideOut(); burgerTask.setRate(-1.0); @@ -1124,115 +941,91 @@ public class MainWindowController { public void editBtnReturn(String title, String coverPath, String romPath, String titleID) { dbController.setGameInfo(title, coverPath, romPath, titleID); games.remove(selectedUIDataIndex); - dbController.loadSingleGame(titleID); + games.add(dbController.loadSingleGame(titleID)); + addGame(games.stream().filter(x -> x.getRomPath().equals(romPath)).findFirst().orElse(null)); refreshUIData(); LOGGER.info("successfully edited " + titleID + ", new name is \"" + title + "\""); } - + /** - * add game to games (ArrayList) and initialize all needed actions (start, time stamps, titleID) - * @param title : game title - * @param coverPath : path to cover (cache) - * @param romPath : path to ROM file (.rpx) - * @param titleID : game ID + * add the context menu and button action for all games */ - public void addGame(String title, String coverPath, String romPath, String titleID){ - VBox VBox = new VBox(); - Label gameTitleLabel = new Label(); - JFXButton gameBtn = new JFXButton(); - ImageView imageView = new ImageView(); - Image coverImage = new Image(new File(coverPath).toURI().toString()); + private void addAllGames() { + for (UIROMDataType game : games) { + addGame(game); + } - generatePosition(); - - UIROMDataType uiROMElement = new UIROMDataType(VBox, gameTitleLabel, gameBtn, imageView, titleID, romPath); - - uiROMElement.getLabel().setText(title); - uiROMElement.getLabel().setMaxWidth(200); - uiROMElement.getLabel().setPadding(new Insets(0,0,0,8)); - uiROMElement.getLabel().setFont(Font.font("System", FontWeight.BOLD, 14)); - - // i think we can do this locally and remove the imageView from the data type since it's used as graphic - uiROMElement.getImageView().setImage(coverImage); - uiROMElement.getImageView().setFitHeight(300); - uiROMElement.getImageView().setFitWidth(200); - - uiROMElement.getButton().setGraphic(uiROMElement.getImageView()); - uiROMElement.getButton().setContextMenu(gameContextMenu); - uiROMElement.getButton().setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 3); "); - uiROMElement.getButton().addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler() { - @Override - public void handle(MouseEvent event) { - LOGGER.info("selected: " + title + "; ID: " + titleID); - // getting the selected game index by comparing event.getSource() with games.get(i).getButton() - for (int i = 0; i < games.size(); i++) { - if (games.get(i).getButton() == event.getSource()) { - selectedUIDataIndex = i; - } + refreshUIData(); // refresh the list of games displayed on screen + } + + /** + * add the context menu and button action for one game + * @param game a game + */ + private void addGame(UIROMDataType game) { + game.getButton().setContextMenu(gameContextMenu); + game.getButton().addEventHandler(MouseEvent.MOUSE_CLICKED, (event) -> { + LOGGER.info("selected: " + game.getLabel().getText() + "; ID: " + game.getTitleID()); + // getting the selected game index by comparing event.getSource() with games.get(i).getButton() + for (int i = 0; i < games.size(); i++) { + if (games.get(i).getButton() == event.getSource()) { + selectedUIDataIndex = i; } + } - gameExecutePath = romPath; - selectedGameTitleID = titleID; - selectedGameTitle = title; + gameExecutePath = game.getRomPath(); + selectedGameTitleID = game.getTitleID(); + selectedGameTitle = game.getName(); - // underlining selected Label - lastGameLabel.setStyle("-fx-underline: false;"); - games.get(selectedUIDataIndex).getLabel().setStyle("-fx-underline: true;"); - lastGameLabel = games.get(selectedUIDataIndex).getLabel(); + // underlining selected Label + lastGameLabel.setStyle("-fx-underline: false;"); + games.get(selectedUIDataIndex).getLabel().setStyle("-fx-underline: true;"); + lastGameLabel = games.get(selectedUIDataIndex).getLabel(); - // setting last played, if lastPlayed is empty game was never played before, else set correct date - if (dbController.getLastPlayed(titleID).equals("") || dbController.getLastPlayed(titleID).equals(null)) { - lastTimePlayedBtn.setText(lastPlayed + never); - totalPlaytimeBtn.setText(dbController.getTotalPlaytime(titleID) + " min"); + // setting last played, if lastPlayed is empty game was never played before, else set correct date + if (dbController.getLastPlayed(game.getTitleID()).equals("") || dbController.getLastPlayed(game.getTitleID()).equals(null)) { + lastTimePlayedBtn.setText(lastPlayed + never); + totalPlaytimeBtn.setText(dbController.getTotalPlaytime(game.getTitleID()) + " min"); + } else { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + int tToday = Integer.parseInt(dtf.format(LocalDate.now()).replaceAll("-", "")); + int tYesterday = Integer.parseInt(dtf.format(LocalDate.now().minusDays(1)).replaceAll("-", "")); + int tLastPlayedDay = Integer.parseInt(dbController.getLastPlayed(game.getTitleID()).replaceAll("-", "")); + + if (tLastPlayedDay == tToday) { + lastTimePlayedBtn.setText(lastPlayed + today); + } else if (tLastPlayedDay == tYesterday) { + lastTimePlayedBtn.setText(lastPlayed + yesterday); } else { - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - - int tToday = Integer.parseInt(dtf.format(LocalDate.now()).replaceAll("-", "")); - int tYesterday = Integer.parseInt(dtf.format(LocalDate.now().minusDays(1)).replaceAll("-", "")); - int tLastPlayedDay = Integer.parseInt(dbController.getLastPlayed(titleID).replaceAll("-", "")); - - if (tLastPlayedDay == tToday) { - lastTimePlayedBtn.setText(lastPlayed + today); - } else if (tLastPlayedDay == tYesterday) { - lastTimePlayedBtn.setText(lastPlayed + yesterday); - } else { - lastTimePlayedBtn.setText(lastPlayed + dbController.getLastPlayed(titleID)); - } + lastTimePlayedBtn.setText(lastPlayed + dbController.getLastPlayed(game.getTitleID())); } + } - /** - * setting total playtime, if total playtime > 60 minutes, format is "x hours x - * minutes" (x h x min), else only minutes are showed - */ - if (Integer.parseInt(dbController.getTotalPlaytime(titleID)) > 60) { - int hoursPlayed = (int) Math.floor(Integer.parseInt(dbController.getTotalPlaytime(titleID)) / 60); - int minutesPlayed = Integer.parseInt(dbController.getTotalPlaytime(titleID)) - 60 * hoursPlayed; - totalPlaytimeBtn.setText(hoursPlayed + " h " + minutesPlayed + " min"); - } else { - totalPlaytimeBtn.setText(dbController.getTotalPlaytime(titleID) + " min"); - } - - if (!playTrue) { - playBtnSlideIn(); - } - if (menuTrue) { - sideMenuSlideOut(); - burgerTask.setRate(-1.0); - burgerTask.play(); - menuTrue = false; - } + /** + * setting total playtime, if total playtime > 60 minutes, format is "x hours x + * minutes" (x h x min), else only minutes are showed + */ + if (Integer.parseInt(dbController.getTotalPlaytime(game.getTitleID())) > 60) { + int hoursPlayed = (int) Math.floor(Integer.parseInt(dbController.getTotalPlaytime(game.getTitleID())) / 60); + int minutesPlayed = Integer.parseInt(dbController.getTotalPlaytime(game.getTitleID())) - 60 * hoursPlayed; + totalPlaytimeBtn.setText(hoursPlayed + " h " + minutesPlayed + " min"); + } else { + totalPlaytimeBtn.setText(dbController.getTotalPlaytime(game.getTitleID()) + " min"); + } + if (!playTrue) { + playBtnSlideIn(); + } + if (menuTrue) { + sideMenuSlideOut(); + burgerTask.setRate(-1.0); + burgerTask.play(); + menuTrue = false; } }); - - uiROMElement.getVBox().setLayoutX(getxPos()); - uiROMElement.getVBox().setLayoutY(getyPos()); - uiROMElement.getVBox().getChildren().addAll(gameTitleLabel,gameBtn); - - // add uiROMElement to games list - games.add(uiROMElement); - } + } /** * reload all ROMs from the ROM directory @@ -1240,140 +1033,97 @@ public class MainWindowController { public void reloadRoms() { JFXSpinner spinner = new JFXSpinner(); spinner.setPrefSize(30, 30); - AnchorPane.setTopAnchor(spinner, (main.getPane().getPrefHeight()-spinner.getPrefHeight())/2); - AnchorPane.setLeftAnchor(spinner, (main.getPane().getPrefWidth()-spinner.getPrefWidth())/2); - - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - Platform.runLater(() -> { - //remove all games form gamesAnchorPane - gamesAnchorPane.getChildren().removeAll(gamesAnchorPane.getChildren()); - main.getPane().getChildren().add(spinner); // add spinner to pane - }); - - dbController.loadRomDirectory(getRomDirectoryPath()); // reload the ROM directory - games.removeAll(games); // remove all games from the mwc game list - dbController.loadAllGames(); // load all games from the database to the mwc - - Platform.runLater(() -> { - refreshUIData(); // refresh the list of games displayed on screen - main.getPane().getChildren().remove(spinner); - }); - } - }); - thread.start(); + AnchorPane.setTopAnchor(spinner, (mainAnchorPane.getPrefHeight() - spinner.getPrefHeight()) / 2); + AnchorPane.setLeftAnchor(spinner, (mainAnchorPane.getPrefWidth() - spinner.getPrefWidth()) / 2); + + Runnable task = () -> { + Platform.runLater(() -> { + gamesFlowPane.getChildren().clear(); //remove all games form gamesFlowPane + mainAnchorPane.getChildren().add(spinner); // add spinner to mainAnchorPane + }); + + dbController.loadRomDirectory(XMLController.getRomDirectoryPath()); // reload the ROM directory + games.clear(); // remove all games from the mwc game list + games = dbController.loadAllGames(); + addAllGames(); + + Platform.runLater(() -> { + mainAnchorPane.getChildren().remove(spinner); + }); + }; + + new Thread(task).start(); } - //remove all games from gamesAnchorPane and add them afterwards - public void refreshUIData() { - //remove all games form gamesAnchorPane - gamesAnchorPane.getChildren().removeAll(gamesAnchorPane.getChildren()); - - //reset position - xPos = -200; - yPos = 17; - xPosHelper = 0; - - //add all games to gamesAnchorPane (UI) - for(int i=0; i< games.size(); i++){ - generatePosition(); - games.get(i).getVBox().setLayoutX(getxPos()); - games.get(i).getVBox().setLayoutY(getyPos()); - gamesAnchorPane.getChildren().add(games.get(i).getVBox()); - } - } + // remove all games from gamesFlowPane and add them afterwards + public void refreshUIData() { + gamesFlowPane.getChildren().clear(); + gamesFlowPane.getChildren().addAll(games); + } // set the selected local strings to all needed elements void setUILanguage(){ - switch(getLanguage()){ - case "en_US": - bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US); //us_English + switch (XMLController.getUsrLocal()) { + case "en_US": + XMLController.setLocalBundle(ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US)); // us_English languageChoisBox.getSelectionModel().select(0); break; - case "de_DE": - bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.GERMAN); //German - languageChoisBox.getSelectionModel().select(1); + case "de_DE": + XMLController.setLocalBundle(ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.GERMAN)); // German + languageChoisBox.getSelectionModel().select(1); break; - default: - bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US); //default local - languageChoisBox.getSelectionModel().select(0); + default: + XMLController.setLocalBundle(ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US)); // default local + languageChoisBox.getSelectionModel().select(0); break; - } + } // Buttons - aboutBtn.setText(bundle.getString("aboutBtn")); - settingsBtn.setText(bundle.getString("settingsBtn")); - addBtn.setText(bundle.getString("addBtn")); - reloadRomsBtn.setText(bundle.getString("reloadRomsBtn")); - smmdbBtn.setText(bundle.getString("smmdbBtn")); - cemuTFBtn.setText(bundle.getString("cemuTFBtn")); - romTFBtn.setText(bundle.getString("romTFBtn")); - updateBtn.setText(bundle.getString("updateBtnCheckNow")); - smmdbDownloadBtn.setText(bundle.getString("smmdbDownloadBtn")); - playBtn.setText(bundle.getString("playBtn")); - cloudSyncToggleBtn.setText(bundle.getString("cloudSyncToggleBtn")); - autoUpdateToggleBtn.setText(bundle.getString("autoUpdateToggleBtn")); - fullscreenToggleBtn.setText(bundle.getString("fullscreenToggleBtn")); + aboutBtn.setText(XMLController.getLocalBundle().getString("aboutBtn")); + settingsBtn.setText(XMLController.getLocalBundle().getString("settingsBtn")); + addBtn.setText(XMLController.getLocalBundle().getString("addBtn")); + reloadRomsBtn.setText(XMLController.getLocalBundle().getString("reloadRomsBtn")); + smmdbBtn.setText(XMLController.getLocalBundle().getString("smmdbBtn")); + cemuTFBtn.setText(XMLController.getLocalBundle().getString("cemuTFBtn")); + romTFBtn.setText(XMLController.getLocalBundle().getString("romTFBtn")); + updateBtn.setText(XMLController.getLocalBundle().getString("updateBtnCheckNow")); + smmdbDownloadBtn.setText(XMLController.getLocalBundle().getString("smmdbDownloadBtn")); + playBtn.setText(XMLController.getLocalBundle().getString("playBtn")); + cloudSyncToggleBtn.setText(XMLController.getLocalBundle().getString("cloudSyncToggleBtn")); + autoUpdateToggleBtn.setText(XMLController.getLocalBundle().getString("autoUpdateToggleBtn")); + fullscreenToggleBtn.setText(XMLController.getLocalBundle().getString("fullscreenToggleBtn")); // Labels - cemu_UISettingsLbl.setText(bundle.getString("cemu_UISettingsLbl")); - cemuDirectoryLbl.setText(bundle.getString("cemuDirectoryLbl")); - romDirectoryLbl.setText(bundle.getString("romDirectoryLbl")); - mainColorLbl.setText(bundle.getString("mainColorLbl")); - languageLbl.setText(bundle.getString("languageLbl")); - updateLbl.setText(bundle.getString("updateLbl")); - branchLbl.setText(bundle.getString("branchLbl")); - cemuSettingsLbl.setText(bundle.getString("cemuSettingsLbl")); - licensesLbl.setText(bundle.getString("licensesLbl")); + cemu_UISettingsLbl.setText(XMLController.getLocalBundle().getString("cemu_UISettingsLbl")); + cemuDirectoryLbl.setText(XMLController.getLocalBundle().getString("cemuDirectoryLbl")); + romDirectoryLbl.setText(XMLController.getLocalBundle().getString("romDirectoryLbl")); + mainColorLbl.setText(XMLController.getLocalBundle().getString("mainColorLbl")); + languageLbl.setText(XMLController.getLocalBundle().getString("languageLbl")); + updateLbl.setText(XMLController.getLocalBundle().getString("updateLbl")); + branchLbl.setText(XMLController.getLocalBundle().getString("branchLbl")); + cemuSettingsLbl.setText(XMLController.getLocalBundle().getString("cemuSettingsLbl")); + licensesLbl.setText(XMLController.getLocalBundle().getString("licensesLbl")); // Columns - titleColumn.setText(bundle.getString("titleColumn")); - idColumn.setText(bundle.getString("idColumn")); - starsColumn.setText(bundle.getString("starsColumn")); - timeColumn.setText(bundle.getString("timeColumn")); + titleColumn.setText(XMLController.getLocalBundle().getString("titleColumn")); + idColumn.setText(XMLController.getLocalBundle().getString("idColumn")); + starsColumn.setText(XMLController.getLocalBundle().getString("starsColumn")); + timeColumn.setText(XMLController.getLocalBundle().getString("timeColumn")); // Strings - editHeadingText = bundle.getString("editHeadingText"); - editBodyText = bundle.getString("editBodyText"); - removeHeadingText = bundle.getString("removeHeadingText"); - removeBodyText = bundle.getString("removeBodyText"); - addUpdateHeadingText = bundle.getString("addUpdateHeadingText"); - addUpdateBodyText = bundle.getString("addUpdateBodyText"); - addDLCHeadingText = bundle.getString("addDLCHeadingText"); - addDLCBodyText = bundle.getString("addDLCBodyText"); - licensesLblHeadingText = bundle.getString("licensesLblHeadingText"); - licensesLblBodyText = bundle.getString("licensesLblBodyText"); - showLicenses = bundle.getString("showLicenses"); - aboutBtnHeadingText = bundle.getString("aboutBtnHeadingText"); - aboutBtnBodyText = bundle.getString("aboutBtnBodyText"); - cloudSyncWaringHeadingText = bundle.getString("cloudSyncWaringHeadingText"); - cloudSyncWaringBodyText = bundle.getString("cloudSyncWaringBodyText"); - cloudSyncErrorHeadingText = bundle.getString("cloudSyncErrorHeadingText"); - cloudSyncErrorBodyText = bundle.getString("cloudSyncErrorBodyText"); - addGameBtnHeadingText = bundle.getString("addGameBtnHeadingText"); - addGameBtnBodyText = bundle.getString("addGameBtnBodyText"); - addBtnReturnErrorHeadingText = bundle.getString("addBtnReturnErrorHeadingText"); - addBtnReturnErrorBodyText = bundle.getString("addBtnReturnErrorBodyText"); - lastPlayed = bundle.getString("lastPlayed"); - today = bundle.getString("today"); - yesterday = bundle.getString("yesterday"); - never = bundle.getString("never"); - - playBtnPlay = bundle.getString("playBtnPlay"); - playBtnUpdating = bundle.getString("playBtnUpdating"); - playBtnCopyingFiles = bundle.getString("playBtnCopyingFiles"); - smmdbDownloadBtnLoading = bundle.getString("smmdbDownloadBtnLoading"); - smmdbDownloadBtnDownload = bundle.getString("smmdbDownloadBtnDownload"); + lastPlayed = XMLController.getLocalBundle().getString("lastPlayed"); + today = XMLController.getLocalBundle().getString("today"); + yesterday = XMLController.getLocalBundle().getString("yesterday"); + never = XMLController.getLocalBundle().getString("never"); } // if AutoUpdate, then check for updates private void checkAutoUpdate() { - if (isAutoUpdate()) { + if (XMLController.isAutoUpdate()) { try { LOGGER.info("AutoUpdate: looking for updates on startup ..."); - updateController = new UpdateController(this, buildNumber, useBeta); + UpdateController updateController = new UpdateController(this, buildNumber, XMLController.isUseBeta()); Thread updateThread = new Thread(updateController); updateThread.setName("Updater"); updateThread.start(); @@ -1503,230 +1253,59 @@ public class MainWindowController { } } - - /** - * xPosHelper based on window width = -24(Windows)/-36(Linux) - * calculates how many games can be displayed in one row - */ - private void generatePosition() { - int xPosHelperMax = (int) Math.floor((mainAnchorPane.getWidth() - 36) / 217); - - if(xPosHelper == xPosHelperMax){ - oldXPosHelper = xPosHelper; - xPos = 17; - yPos = yPos + 345; - xPosHelper = 1; - }else{ - xPos = xPos + 217; - xPosHelper++; - } - } // change the color of all needed GUI elements private void applyColor() { - String boxStyle = "-fx-background-color: #"+getColor()+";"; - String btnStyleBlack = "-fx-button-type: RAISED; -fx-background-color: #"+getColor()+"; -fx-text-fill: BLACK;"; - String btnStyleWhite = "-fx-button-type: RAISED; -fx-background-color: #"+getColor()+"; -fx-text-fill: WHITE;"; - BigInteger icolor = new BigInteger(getColor(),16); + String boxStyle = "-fx-background-color: #" + XMLController.getColor() + ";"; + String textFill = ""; + BigInteger icolor = new BigInteger(XMLController.getColor(),16); BigInteger ccolor = new BigInteger("78909cff",16); sideMenuVBox.setStyle(boxStyle); topHBox.setStyle(boxStyle); - cemuTextField.setFocusColor(Color.valueOf(getColor())); - romTextField.setFocusColor(Color.valueOf(getColor())); + cemuTextField.setFocusColor(Color.valueOf(XMLController.getColor())); + romTextField.setFocusColor(Color.valueOf(XMLController.getColor())); if (icolor.compareTo(ccolor) == -1) { - dialogBtnStyle = btnStyleWhite; + textFill = "-fx-text-fill: WHITE;"; - aboutBtn.setStyle("-fx-text-fill: WHITE;"); - settingsBtn.setStyle("-fx-text-fill: WHITE;"); - addBtn.setStyle("-fx-text-fill: WHITE;"); - reloadRomsBtn.setStyle("-fx-text-fill: WHITE;"); - smmdbBtn.setStyle("-fx-text-fill: WHITE;"); - playBtn.setStyle("-fx-text-fill: WHITE; -fx-font-family: Roboto Medium;"); - cemuTFBtn.setStyle(btnStyleWhite); - romTFBtn.setStyle(btnStyleWhite); - updateBtn.setStyle(btnStyleWhite); - smmdbDownloadBtn.setStyle(btnStyleWhite); - playBtn.setStyle(btnStyleWhite); - - aboutBtn.setGraphic(info_white); - settingsBtn.setGraphic(settings_white); - addBtn.setGraphic(add_circle_white); - reloadRomsBtn.setGraphic(cached_white); - smmdbBtn.setGraphic(smmdb_white); + aboutBtn.setGraphic(new ImageView(new Image("icons/ic_info_white_24dp_1x.png"))); + settingsBtn.setGraphic(new ImageView(new Image("icons/ic_settings_white_24dp_1x.png"))); + addBtn.setGraphic(new ImageView(new Image("icons/ic_add_circle_white_24dp_1x.png"))); + reloadRomsBtn.setGraphic(new ImageView(new Image("icons/ic_cached_white_24dp_1x.png"))); + smmdbBtn.setGraphic(new ImageView(new Image("icons/ic_get_app_white_24dp_1x.png"))); menuHam.getStyleClass().clear(); menuHam.getStyleClass().add("jfx-hamburgerW"); } else { - dialogBtnStyle = btnStyleBlack; - - aboutBtn.setStyle("-fx-text-fill: BLACK;"); - settingsBtn.setStyle("-fx-text-fill: BLACK;"); - addBtn.setStyle("-fx-text-fill: BLACK;"); - reloadRomsBtn.setStyle("-fx-text-fill: BLACK;"); - smmdbBtn.setStyle("-fx-text-fill: BLACK;"); - playBtn.setStyle("-fx-text-fill: BLACK; -fx-font-family: Roboto Medium;"); - cemuTFBtn.setStyle(btnStyleBlack); - romTFBtn.setStyle(btnStyleBlack); - updateBtn.setStyle(btnStyleBlack); - smmdbDownloadBtn.setStyle(btnStyleBlack); - playBtn.setStyle(btnStyleBlack); - - aboutBtn.setGraphic(info_black); - settingsBtn.setGraphic(settings_black); - addBtn.setGraphic(add_circle_black); - reloadRomsBtn.setGraphic(cached_black); - smmdbBtn.setGraphic(smmdb_black); + textFill = "-fx-text-fill: BLACK;"; + + aboutBtn.setGraphic(new ImageView(new Image("icons/ic_info_black_24dp_1x.png"))); + settingsBtn.setGraphic(new ImageView(new Image("icons/ic_settings_black_24dp_1x.png"))); + addBtn.setGraphic(new ImageView(new Image("icons/ic_add_circle_black_24dp_1x.png"))); + reloadRomsBtn.setGraphic(new ImageView(new Image("icons/ic_cached_black_24dp_1x.png"))); + smmdbBtn.setGraphic(new ImageView(new Image("icons/ic_get_app_black_24dp_1x.png"))); menuHam.getStyleClass().clear(); menuHam.getStyleClass().add("jfx-hamburgerB"); } - - for (int i = 0; i < games.size(); i++) { - games.get(i).getButton().setRipplerFill(Paint.valueOf(getColor())); - } - } - - /** - * save settings to the config.xml file - */ - public void saveSettings() { - LOGGER.info("saving Settings ..."); - - try { - props.setProperty("cemuPath", getCemuPath()); - props.setProperty("romPath", getRomDirectoryPath()); - props.setProperty("color", getColor()); - props.setProperty("language", getLanguage()); - props.setProperty("fullscreen", String.valueOf(isFullscreen())); - props.setProperty("cloudSync", String.valueOf(isCloudSync())); - props.setProperty("autoUpdate", String.valueOf(isAutoUpdate())); - props.setProperty("useBeta", String.valueOf(isUseBeta())); - if (getCloudService() == null) { - props.setProperty("cloudService", ""); - } else { - props.setProperty("cloudService", getCloudService()); - } - props.setProperty("folderID", main.getCloudController().getFolderID(getCloudService())); - props.setProperty("lastLocalSync", String.valueOf(getLastLocalSync())); - props.setProperty("windowWidth", String.valueOf(mainAnchorPane.getWidth())); - props.setProperty("windowHeight", String.valueOf(mainAnchorPane.getHeight())); - - OutputStream outputStream = new FileOutputStream(main.getConfigFile()); // new output-stream - props.storeToXML(outputStream, "cemu_UI settings"); // write new .xml - outputStream.close(); - LOGGER.info("saving Settings done!"); - } catch (IOException e) { - LOGGER.error("an error occured", e); - } - } - - /** - * loading saved settings from the config.xml file - * if a value is not present, default is used instead - */ - private void loadSettings() { - LOGGER.info("loading settings ..."); - try { - InputStream inputStream = new FileInputStream(main.getConfigFile()); - props.loadFromXML(inputStream); // new input-stream from .xml - - try { - setCemuPath(props.getProperty("cemuPath")); - } catch (Exception e) { - LOGGER.error("cloud not load cemuPath", e); - setCemuPath(""); - } - - try { - setRomDirectoryPath(props.getProperty("romPath")); - } catch (Exception e) { - LOGGER.error("could not load romPath", e); - setRomDirectoryPath(""); - } - - try { - setColor(props.getProperty("color")); - } catch (Exception e) { - LOGGER.error("could not load color value, setting default instead", e); - setColor("00a8cc"); - } - - if (props.getProperty("language") == null) { - LOGGER.error("cloud not load language, setting default instead"); - setLanguage("en_US"); - } else { - setLanguage(props.getProperty("language")); - } - - try { - setFullscreen(Boolean.parseBoolean(props.getProperty("fullscreen"))); - } catch (Exception e) { - LOGGER.error("could not load fullscreen, setting default instead", e); - setFullscreen(false); - } - - try { - setCloudSync(Boolean.parseBoolean(props.getProperty("cloudSync"))); - } catch (Exception e) { - LOGGER.error("could not load cloudSync, setting default instead", e); - setCloudSync(false); - } - - try { - setAutoUpdate(Boolean.parseBoolean(props.getProperty("autoUpdate"))); - } catch (Exception e) { - LOGGER.error("cloud not load autoUpdate", e); - setAutoUpdate(false); - } - - try { - setUseBeta(Boolean.parseBoolean(props.getProperty("useBeta"))); - } catch (Exception e) { - LOGGER.error("cloud not load autoUpdate", e); - setUseBeta(false); - } - - try { - setCloudService(props.getProperty("cloudService")); - } catch (Exception e) { - LOGGER.error("could not load cloudSync", e); - setCloudService(""); - } - - try { - main.getCloudController().setFolderID(props.getProperty("folderID"), getCloudService()); - } catch (Exception e) { - LOGGER.error("could not load folderID, disable cloud sync. Please contact an developer", e); - setCloudSync(false); - } - - try { - setLastLocalSync(Long.parseLong(props.getProperty("lastLocalSync"))); - } catch (Exception e) { - LOGGER.error("could not load lastSuccessSync, setting default instead", e); - setLastLocalSync(0); - } - - try { - setWindowWidth(Double.parseDouble(props.getProperty("windowWidth"))); - } catch (Exception e) { - LOGGER.error("could not load windowWidth, setting default instead", e); - setWindowWidth(904); - } - - try { - setWindowHeight(Double.parseDouble(props.getProperty("windowHeight"))); - } catch (Exception e) { - LOGGER.error("could not load windowHeight, setting default instead", e); - setWindowHeight(600); - } - - inputStream.close(); - LOGGER.info("loading settings done!"); - } catch (IOException e) { - LOGGER.error("an error occured", e); + + btnStyle = "-fx-button-type: RAISED; -fx-background-color: #" + XMLController.getColor() + "; " + textFill; + + aboutBtn.setStyle(textFill); + settingsBtn.setStyle(textFill); + addBtn.setStyle(textFill); + reloadRomsBtn.setStyle(textFill); + smmdbBtn.setStyle(textFill); + playBtn.setStyle(textFill); + cemuTFBtn.setStyle(btnStyle); + romTFBtn.setStyle(btnStyle); + updateBtn.setStyle(btnStyle); + smmdbDownloadBtn.setStyle(btnStyle); + playBtn.setStyle(btnStyle); + + for(UIROMDataType game : games) { + game.getButton().setRipplerFill(Paint.valueOf(XMLController.getColor())); } } @@ -1768,8 +1347,8 @@ public class MainWindowController { private void editColor(String input){ StringBuilder sb = new StringBuilder(input); sb.delete(0, 2); - this.color = sb.toString(); - saveSettings(); + XMLController.setColor(sb.toString()); + xmlController.saveSettings(); } @SuppressWarnings("unused") @@ -1777,8 +1356,8 @@ public class MainWindowController { * @return the main color in hexadecimal format */ private String hexToRgb() { - LOGGER.info(getColor()); - int hex = Integer.parseInt(getColor().substring(0, 5), 16); + LOGGER.info(XMLController.getColor()); + int hex = Integer.parseInt(XMLController.getColor().substring(0, 5), 16); int r = (hex & 0xFF0000) >> 16; int g = (hex & 0xFF00) >> 8; @@ -1803,105 +1382,9 @@ public class MainWindowController { return resizedImage; } - - public Main getMain() { - return main; - } - - public DBController getDbController() { - return dbController; - } - - public void setMainAnchorPane(AnchorPane mainAnchorPane) { - this.mainAnchorPane = mainAnchorPane; - } - - public String getCemuPath() { - return cemuPath; - } - - public void setCemuPath(String cemuPath) { - this.cemuPath = cemuPath; - } - public String getRomDirectoryPath() { - return romDirectoryPath; - } - - public void setRomDirectoryPath(String romDirectoryPath) { - this.romDirectoryPath = romDirectoryPath; - } - - public String getColor() { - return color; - } - - public void setColor(String color) { - this.color = color; - } - - public int getxPos() { - return xPos; - } - - public void setxPos(int xPos) { - this.xPos = xPos; - } - - public int getyPos() { - return yPos; - } - - public void setyPos(int yPos) { - this.yPos = yPos; - } - - public int getxPosHelper() { - return xPosHelper; - } - - public void setxPosHelper(int xPosHelper) { - this.xPosHelper = xPosHelper; - } - - public long getLastLocalSync() { - return lastLocalSync; - } - - public void setLastLocalSync(long lastLocalSync) { - this.lastLocalSync = lastLocalSync; - } - - public boolean isFullscreen() { - return fullscreen; - } - - public void setFullscreen(boolean fullscreen) { - this.fullscreen = fullscreen; - } - - public boolean isCloudSync() { - return cloudSync; - } - - public void setCloudSync(boolean cloudSync) { - this.cloudSync = cloudSync; - } - - public boolean isAutoUpdate() { - return autoUpdate; - } - - public void setAutoUpdate(boolean autoUpdate) { - this.autoUpdate = autoUpdate; - } - - public boolean isUseBeta() { - return useBeta; - } - - public void setUseBeta(boolean useBeta) { - this.useBeta = useBeta; + public Stage getPrimaryStage() { + return primaryStage; } public String getGameExecutePath() { @@ -1920,14 +1403,6 @@ public class MainWindowController { this.selectedGameTitleID = selectedGameTitleID; } - public String getCloudService() { - return cloudService; - } - - public void setCloudService(String cloudService) { - this.cloudService = cloudService; - } - public JFXButton getPlayBtn() { return playBtn; } @@ -1936,46 +1411,6 @@ public class MainWindowController { this.playBtn = playBtn; } - public double getWindowWidth() { - return windowWidth; - } - - public void setWindowWidth(double windowWidth) { - this.windowWidth = windowWidth; - } - - public double getWindowHeight() { - return windowHeight; - } - - public void setWindowHeight(double windowHeight) { - this.windowHeight = windowHeight; - } - - public int getOldXPosHelper() { - return oldXPosHelper; - } - - public void setOldXPosHelper(int oldXPosHelper) { - this.oldXPosHelper = oldXPosHelper; - } - - public String getLanguage() { - return language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public ResourceBundle getBundle() { - return bundle; - } - - public void setBundle(ResourceBundle bundle) { - this.bundle = bundle; - } - public AnchorPane getMainAnchorPane() { return mainAnchorPane; } diff --git a/src/main/java/com/cemu_UI/application/playGame.java b/src/main/java/com/cemu_UI/application/playGame.java index 651504a..13ee646 100644 --- a/src/main/java/com/cemu_UI/application/playGame.java +++ b/src/main/java/com/cemu_UI/application/playGame.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.application; import java.io.IOException; @@ -26,11 +27,13 @@ import java.time.Instant; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.cemu_UI.controller.CloudController; import com.cemu_UI.controller.DBController; +import com.cemu_UI.controller.XMLController; import javafx.application.Platform; -public class playGame extends Thread{ +public class playGame extends Thread { private MainWindowController mainWindowController; private DBController dbController; @@ -44,7 +47,7 @@ public class playGame extends Thread{ @Override public void run() { String selectedGameTitleID = mainWindowController.getSelectedGameTitleID(); - String cemuBin = mainWindowController.getCemuPath() + "/Cemu.exe"; + String cemuBin = XMLController.getCemuPath() + "/Cemu.exe"; String gameExec = "\"" + mainWindowController.getGameExecutePath() + "\""; long startTime; long endTime; @@ -53,18 +56,18 @@ public class playGame extends Thread{ Process p; Platform.runLater(() -> { - mainWindowController.getMain().getPrimaryStage().setIconified(true); // minimize cemu_UI + mainWindowController.getPrimaryStage().setIconified(true); // minimize cemu_UI }); startTime = System.currentTimeMillis(); try { if (System.getProperty("os.name").equals("Linux")) { - if(mainWindowController.isFullscreen()){ + if(XMLController.isFullscreen()){ p = new ProcessBuilder("wine", cemuBin, "-f", "-g", gameExec).start(); } else { p = new ProcessBuilder("wine", cemuBin, "-g", gameExec).start(); } } else { - if(mainWindowController.isFullscreen()){ + if(XMLController.isFullscreen()){ p = new ProcessBuilder(cemuBin, "-f", "-g", gameExec).start(); } else { p = new ProcessBuilder(cemuBin, "-g", gameExec).start(); @@ -85,14 +88,14 @@ public class playGame extends Thread{ } else { mainWindowController.totalPlaytimeBtn.setText(dbController.getTotalPlaytime(selectedGameTitleID) + " min"); } - mainWindowController.getMain().getPrimaryStage().setIconified(false); // maximize cemu_UI + mainWindowController.getPrimaryStage().setIconified(false); // maximize cemu_UI }); //sync savegame with cloud service - if (mainWindowController.isCloudSync()) { - mainWindowController.setLastLocalSync(Instant.now().getEpochSecond()); - mainWindowController.getMain().getCloudController().sync(mainWindowController.getCloudService(), - mainWindowController.getCemuPath(), mainWindowController.getMain().getDirectory().getPath()); + if (XMLController.isCloudSync()) { + XMLController.setLastLocalSync(Instant.now().getEpochSecond()); + CloudController.getInstance(mainWindowController).sync(XMLController.getCloudService(), + XMLController.getCemuPath(), XMLController.getDirCemuUIPath()); } } catch (IOException | InterruptedException e) { diff --git a/src/main/java/com/cemu_UI/controller/CloudController.java b/src/main/java/com/cemu_UI/controller/CloudController.java index 6e3f385..5b66f47 100644 --- a/src/main/java/com/cemu_UI/controller/CloudController.java +++ b/src/main/java/com/cemu_UI/controller/CloudController.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.controller; import java.io.File; @@ -32,6 +33,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.cemu_UI.application.MainWindowController; +import com.cemu_UI.datatypes.GlobalDataTypes.CloudService; import com.cemu_UI.vendorCloudController.GoogleDriveController; import javafx.application.Platform; @@ -39,20 +41,32 @@ import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; public class CloudController { - + + // TODO make singleton + + private MainWindowController mwc; + private static CloudController instance = null; + private XMLController xmlController = new XMLController(); + private GoogleDriveController googleDriveController = new GoogleDriveController(); + private static final Logger LOGGER = LogManager.getLogger(CloudController.class.getName()); + public CloudController(MainWindowController mwc) { this.mwc = mwc; } - private MainWindowController mwc; - private GoogleDriveController googleDriveController = new GoogleDriveController(); - private static final Logger LOGGER = LogManager.getLogger(CloudController.class.getName()); + public static CloudController getInstance(MainWindowController mwc) { + if (instance == null) { + instance = new CloudController(mwc); + } + + return instance; + } - public boolean initializeConnection(String cloudService, String cemuDirectory) { + public boolean initializeConnection(CloudService cloudService, String cemuDirectory) { boolean success = false; LOGGER.info("sartting cloud initialisation ..."); - if(cloudService.equals("GoogleDrive")) { + if(cloudService == CloudService.GoogleDrive) { LOGGER.info("selected service is Google Drive"); try { googleDriveController.main(cemuDirectory); @@ -63,7 +77,7 @@ public class CloudController { success = true; } - if(cloudService.equals("Dropbox")) { + if(cloudService == CloudService.Dropbox) { LOGGER.info("selected service is Dropbox"); } LOGGER.info("cloud initialisation done!"); @@ -76,7 +90,7 @@ public class CloudController { * @param cemuDirectory * @param cemu_UIDirectory */ - public void sync(String cloudService, String cemuDirectory, String cemu_UIDirectory) { + public void sync(CloudService cloudService, String cemuDirectory, String cemu_UIDirectory) { // running sync in a new thread, instead of blocking the main thread Thread thread = new Thread(new Runnable() { @@ -88,61 +102,59 @@ public class CloudController { mwc.getPlayBtn().setText("syncing..."); }); LOGGER.info("starting synchronization in new thread ..."); - + // zip the saves folder File zipFile = zipSavegames(cemu_UIDirectory, cemuDirectory); // upload the zip switch (cloudService) { - + // use GoogleDriveController - case "GoogleDrive": + case GoogleDrive: LOGGER.info("using GoogleDriveController"); long lastCloudSync = googleDriveController.getLastCloudSync(); - + if (!googleDriveController.checkFolder()) { LOGGER.info("cloud sync folder dosen't exist, creating one!"); googleDriveController.creatFolder(); googleDriveController.uploadZipFile(zipFile); - } else if (mwc.getLastLocalSync() > lastCloudSync) { + } else if (XMLController.getLastLocalSync() > lastCloudSync) { LOGGER.info("local is new, going to upload zip"); googleDriveController.uploadZipFile(zipFile); - } else if(mwc.getLastLocalSync() < lastCloudSync) { + } else if (XMLController.getLastLocalSync() < lastCloudSync) { LOGGER.info("cloud is new, going to download zip"); unzipSavegames(cemuDirectory, googleDriveController.downloadZipFile(cemu_UIDirectory)); - mwc.setLastLocalSync(lastCloudSync); + XMLController.setLastLocalSync(lastCloudSync); break; } else { LOGGER.info("nothing to do"); break; } - mwc.setLastLocalSync(Long.parseLong(zipFile.getName().substring(0, zipFile.getName().length()-4))); // set time of last sucessfull sync - break; - - - - case "Dropbox": - + XMLController.setLastLocalSync(Long.parseLong(zipFile.getName().substring(0, zipFile.getName().length() - 4))); // set time of last sucessfull sync + break; + + case Dropbox: + // do the thing break; - default: LOGGER.warn("no cloud vendor found!"); break; } - + zipFile.delete(); // delete zipfile in cem_UI directory Platform.runLater(() -> { mwc.getPlayBtn().setText("play"); mwc.getPlayBtn().setDisable(false); - mwc.saveSettings(); + xmlController.saveSettings(); }); - LOGGER.info("synchronization successful!"); } catch (Exception e) { - LOGGER.error("There was an error during syncronisation! Please open a new issue on the cemu_UI github page:", e); + LOGGER.error( + "There was an error during syncronisation! Please open a new issue on the cemu_UI github page:", + e); } } }); @@ -199,28 +211,17 @@ public class CloudController { } } - public String getFolderID(String cloudService) { + public String getFolderID(CloudService cloudService) { String folderID = ""; if (cloudService != null) { - if (cloudService.equals("GoogleDrive")) { + if (cloudService == CloudService.GoogleDrive) { folderID = googleDriveController.getFolderID(); } - if (cloudService.equals("Dropbox")) { + if (cloudService == CloudService.Dropbox) { } } return folderID; } - - public void setFolderID(String folderID, String cloudService) { - if (cloudService != null) { - if (cloudService.equals("GoogleDrive")) { - googleDriveController.setFolderID(folderID); - } - if (cloudService.equals("Dropbox")) { - - } - } - } } diff --git a/src/main/java/com/cemu_UI/controller/DBController.java b/src/main/java/com/cemu_UI/controller/DBController.java index e4422c3..d29c28f 100644 --- a/src/main/java/com/cemu_UI/controller/DBController.java +++ b/src/main/java/com/cemu_UI/controller/DBController.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.controller; import java.awt.Graphics2D; @@ -27,6 +28,7 @@ import java.io.IOException; import java.net.URL; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -44,95 +46,94 @@ import org.apache.logging.log4j.Logger; import org.w3c.dom.Document; import org.xml.sax.SAXException; -import com.cemu_UI.application.Main; -import com.cemu_UI.application.MainWindowController; +import com.cemu_UI.datatypes.UIROMDataType; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; public class DBController { - - public DBController(Main main, MainWindowController mainWindowController) { - this.main = main; - this.mainWindowController = mainWindowController; - } - - private Main main; - private MainWindowController mainWindowController; + + private static DBController instance = null; private ArrayList entries = new ArrayList<>(); - private String DB_PATH_localRoms; - private String DB_PATH_games; - private Connection connection = null; - private Connection connectionGames = null; + private String DB_PATH_LocalGames; + private String DB_PATH_ReverenceGames; + private Connection connectionLocal = null; + private Connection connectionReverence = null; private static final Logger LOGGER = LogManager.getLogger(DBController.class.getName()); - /** - * initialize the sqlite database controller - * load ROM and games database - * load all games - */ - public void init() { - LOGGER.info("<========== starting loading sql ==========>"); - loadRomDatabase(); - loadGamesDatabase(); - createRomDatabase(); - LOGGER.info("<========== finished loading sql ==========>"); + public DBController() { + + } + + public static DBController getInstance() { + if (instance == null) { + instance = new DBController(); + } + + return instance; } /** - * set the path to the localRoms.db file and initialize the connection + * initialize the {@link DBController} with the database connection check if + * there is a need to create a new database refresh the database + */ + public void init() { + initDatabaseConnection(); + createRomDatabase(); + } + + /** + * create a new connection to the HomeFlix.db database + * AutoCommit is set to false to prevent some issues, so manual commit is active! * * TODO this should be called LocalGames */ - private void loadRomDatabase() { - if (System.getProperty("os.name").equals("Linux")) { - DB_PATH_localRoms = System.getProperty("user.home") + "/cemu_UI/localRoms.db"; - } else { - DB_PATH_localRoms = System.getProperty("user.home") + "\\Documents\\cemu_UI" + "\\" + "localRoms.db"; - } + private void initDatabaseConnection() { + DB_PATH_LocalGames = XMLController.getDirCemuUI() + "/localRoms.db"; + DB_PATH_ReverenceGames = XMLController.getRference_gamesFile().getAbsolutePath(); + try { // create a database connection - connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH_localRoms); - connection.setAutoCommit(false); // AutoCommit to false -> manual commit is active + connectionLocal = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH_LocalGames); + connectionLocal.setAutoCommit(false); + + connectionReverence = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH_ReverenceGames); + connectionReverence.setAutoCommit(false); } catch (SQLException e) { - // if the error message is "out of memory", probably no database file is found - LOGGER.error("error while loading the ROM database", e); + // if the error message is "out of memory", it probably means no database file is found + LOGGER.error("error while loading the Local- or ReverenceGames database", e); } - LOGGER.info("ROM database loaded successfull"); + + LOGGER.info("Local- and ReverenceGames database loaded successfull"); } - /** - * set the path to the localRoms.db file and initialize the connection - * games.db contains a reverence list to for the automatic detection mode - */ - private void loadGamesDatabase() { - DB_PATH_games = main.getReference_gamesFile().getAbsolutePath(); - try { - // create a database connection - connectionGames = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH_games); - connectionGames.setAutoCommit(false); // AutoCommit to false -> manual commit is active - } catch (SQLException e) { - LOGGER.error("error while loading the games database", e); - } - LOGGER.info("games database loaded successfull"); - } - - /** * creating the local_roms table in localRoms.db * if the table has no entries, call loadRomDirectory * - * TODO the local_roms table should be called local_games + * TODO the local_roms table should be called LocalGames */ void createRomDatabase() { try { - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("create table if not exists local_roms (title, coverPath, romPath, titleID, productCode, region, lastPlayed, timePlayed)"); + connectionLocal.commit(); stmt.close(); - connection.commit(); } catch (SQLException e) { - LOGGER.error("error while creating ROM database", e); + LOGGER.error("error while creating local-games database", e); } - + } + + /** + * refresh database to contain all (new added) games + */ + public void refreshDataBase() { + LOGGER.info("<========== starting refreshing database ==========>"); + + entries.clear(); + try { - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms"); while (rs.next()) { entries.add(rs.getString(2)); @@ -142,63 +143,80 @@ public class DBController { } catch (SQLException e) { LOGGER.error("error while loading ROMs from ROM database, local_roms table", e); } + if (entries.size() == 0) { - mainWindowController.reloadRoms(); - } else { loadAllGames(); - mainWindowController.refreshUIData(); } + + LOGGER.info("<========== finished refreshing database ==========>"); } // add a game to the database public void addGame(String title, String coverPath, String romPath, String titleID, String productCode, String region, String lastPlayed, String timePlayed) throws SQLException{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("insert into local_roms values ('"+title+"','"+coverPath+"','"+romPath+"','"+titleID+"'," + "'"+productCode+"','"+region+"','"+lastPlayed+"','"+timePlayed+"')"); - connection.commit(); + connectionLocal.commit(); stmt.close(); LOGGER.info("added \""+title+"\" to ROM database"); } // remove a game from the database public void removeGame(String titleID) throws SQLException{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("delete from local_roms where titleID = '"+titleID+"'"); - connection.commit(); + connectionLocal.commit(); stmt.close(); LOGGER.info("removed \""+titleID+"\" from ROM database"); } - //load all ROMs to the mainWindowController - public void loadAllGames(){ - LOGGER.info("loading all games on startup into the mainWindowController ..."); - try { - Statement stmt = connection.createStatement(); + /** + * load all games from the database to a ObservableList, order entries by title + * @return a ObservableList that contains all local games from the database + */ + public ObservableList loadAllGames() { + ObservableList games = FXCollections.observableArrayList(); + LOGGER.info("loading all local games from the database ..."); + try { + Statement stmt = connectionLocal.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms"); while (rs.next()) { - mainWindowController.addGame(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)); + games.add(new UIROMDataType(rs.getString("romPath"), rs.getString("titleID"), rs.getString("title"), + rs.getString("coverPath"))); } stmt.close(); rs.close(); - }catch (Exception e){ - LOGGER.error("error while loading all games into the mainWindowController", e); + } catch (Exception e) { + LOGGER.error("error while loading all local games from the database", e); } + + return games; } - //load a single ROM to the mainWindowController - public void loadSingleGame(String titleID){ - LOGGER.info("loading a single game (ID: "+titleID+") into the mainWindowController ..."); + /** + * load one game from the database + * @param titleID the titleID of the game you wish to get + * @return the game you asked for + */ + public UIROMDataType loadSingleGame(String titleID) { + UIROMDataType game = null; + LOGGER.info("loading a single game (ID: {}) from the database ...", titleID); try { - Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms where titleID = '"+titleID+"'"); + PreparedStatement ps = connectionLocal.prepareStatement("SELECT * FROM local_roms where titleID = ?"); + ps.setString(1, titleID); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { - mainWindowController.addGame(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)); + game = new UIROMDataType(rs.getString("romPath"), rs.getString("titleID"), rs.getString("title"), + rs.getString("coverPath")); } - stmt.close(); rs.close(); + ps.close(); }catch (Exception e){ LOGGER.error("error while loading a single game into the mainWindowController", e); } + + return game; } /** @@ -209,10 +227,10 @@ public class DBController { File dir = new File(directory); File appFile; String[] extensions = new String[] { "rpx", "jsp" }; - File pictureCache = main.getPictureCache(); + File pictureCache = XMLController.getPictureCache(); String coverPath; try { - Statement stmt = connectionGames.createStatement(); + Statement stmt = connectionReverence.createStatement(); List files = (List) FileUtils.listFiles(dir, extensions, true); LOGGER.info("<============================== start loading ROM Directory ==============================>"); LOGGER.info("Getting all .rpx files in " + dir.getCanonicalPath()+" including those in subdirectories"); @@ -258,7 +276,7 @@ public class DBController { * @throws SQLException */ private boolean checkAddEntry(String title) throws SQLException{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); boolean check = false; ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms WHERE title = '"+title+"';"); while (rs.next()) { @@ -276,15 +294,6 @@ public class DBController { //LOGGER.info("check if entry removed not done yet!"); } - private static BufferedImage resizeImage(BufferedImage originalImage, int type, int IMG_WIDTH, int IMG_HEIGHT) { - BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); - Graphics2D g = resizedImage.createGraphics(); - g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); - g.dispose(); - - return resizedImage; - } - /** * getting info for a game with titleID * @param titleID Title-ID of the Game @@ -294,7 +303,7 @@ public class DBController { String[] gameInfo = new String[4]; LOGGER.info("getting game info for titleID: "+titleID+" ..."); try { - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms where titleID = '"+titleID+"'"); while (rs.next()) { gameInfo[0] = rs.getString(1);// title @@ -313,10 +322,10 @@ public class DBController { public void setGameInfo(String title, String coverPath, String romPath, String titleID){ LOGGER.info("setting game info for titleID: "+titleID+" ..."); try { - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("UPDATE local_roms SET title = '" + title + "', coverPath = '" + coverPath + "'," + " romPath = '" + romPath + "' WHERE titleID = '"+titleID+"';"); - connection.commit(); + connectionLocal.commit(); stmt.close(); }catch (Exception e){ LOGGER.error("error while setting game info", e); @@ -325,9 +334,9 @@ public class DBController { public void setLastPlayed(String titleID){ try{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("UPDATE local_roms SET lastPlayed=date('now') WHERE titleID = '"+titleID+"';"); - connection.commit(); + connectionLocal.commit(); stmt.close(); }catch(SQLException e){ LOGGER.error("failed to set the last played", e); @@ -337,7 +346,7 @@ public class DBController { public String getLastPlayed(String titleID){ String lastPlayed = null; try{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); ResultSet rs = stmt.executeQuery("SELECT lastPlayed FROM local_roms WHERE titleID = '"+titleID+"';" ); lastPlayed = rs.getString(1); stmt.close(); @@ -350,9 +359,9 @@ public class DBController { public void setTotalPlaytime(String timePlayed, String titleID){ try{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); stmt.executeUpdate("UPDATE local_roms SET timePlayed='"+timePlayed+"' WHERE titleID = '"+titleID+"';"); - connection.commit(); + connectionLocal.commit(); stmt.close(); }catch(SQLException e){ LOGGER.error("failed to set total play time", e); @@ -363,7 +372,7 @@ public class DBController { public String getTotalPlaytime(String titleID){ String timePlayed = null; try{ - Statement stmt = connection.createStatement(); + Statement stmt = connectionLocal.createStatement(); ResultSet rs = stmt.executeQuery("SELECT timePlayed FROM local_roms WHERE titleID = '"+titleID+"';" ); timePlayed = rs.getString(1); stmt.close(); @@ -374,5 +383,13 @@ public class DBController { return timePlayed; } + private static BufferedImage resizeImage(BufferedImage originalImage, int type, int IMG_WIDTH, int IMG_HEIGHT) { + BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); + Graphics2D g = resizedImage.createGraphics(); + g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); + g.dispose(); + + return resizedImage; + } } diff --git a/src/main/java/com/cemu_UI/controller/SmmdbAPIController.java b/src/main/java/com/cemu_UI/controller/SmmdbAPIController.java index d683f83..d84626f 100644 --- a/src/main/java/com/cemu_UI/controller/SmmdbAPIController.java +++ b/src/main/java/com/cemu_UI/controller/SmmdbAPIController.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.controller; import java.io.BufferedReader; diff --git a/src/main/java/com/cemu_UI/controller/UpdateController.java b/src/main/java/com/cemu_UI/controller/UpdateController.java index 03aed13..b7cdcc4 100644 --- a/src/main/java/com/cemu_UI/controller/UpdateController.java +++ b/src/main/java/com/cemu_UI/controller/UpdateController.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.controller; import java.io.BufferedReader; @@ -39,21 +40,22 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonArray; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; + import javafx.application.Platform; public class UpdateController implements Runnable { private MainWindowController mainWindowController; - private String buildNumber; + private int buildNumber; + private int updateBuildNumber; // tag_name from gitea private String apiOutput; - private String updateBuildNumber; // tag_name from Github -// private String updateName; -// private String updateChanges; - private String browserDownloadUrl; // update download link - private String githubApiRelease = "https://api.github.com/repos/Seil0/cemu_UI/releases/latest"; - private String githubApiBeta = "https://api.github.com/repos/Seil0/cemu_UI/releases"; - - private URL githubApiUrl; + @SuppressWarnings("unused") + private String updateName; + @SuppressWarnings("unused") + private String updateChanges; + private String browserDownloadUrl; // update download link + private String giteaApiRelease = "https://git.mosad.xyz/api/v1/repos/Seil0/cemu_UI/releases"; + private URL giteaApiUrl; private boolean useBeta; private static final Logger LOGGER = LogManager.getLogger(UpdateController.class.getName()); @@ -62,7 +64,7 @@ public class UpdateController implements Runnable { */ public UpdateController(MainWindowController mwc, String buildNumber, boolean useBeta) { mainWindowController = mwc; - this.buildNumber = buildNumber; + this.buildNumber = Integer.parseInt(buildNumber); this.useBeta = useBeta; } @@ -70,19 +72,13 @@ public class UpdateController implements Runnable { public void run() { LOGGER.info("beta:" + useBeta + "; checking for updates ..."); Platform.runLater(() -> { - mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnChecking")); + mainWindowController.getUpdateBtn().setText(XMLController.getLocalBundle().getString("updateBtnChecking")); }); try { - - if (useBeta) { - githubApiUrl = new URL(githubApiBeta); - } else { - githubApiUrl = new URL(githubApiRelease); - } - - // URL githubApiUrl = new URL(githubApiRelease); - BufferedReader ina = new BufferedReader(new InputStreamReader(githubApiUrl.openStream())); + giteaApiUrl = new URL(giteaApiRelease); + + BufferedReader ina = new BufferedReader(new InputStreamReader(giteaApiUrl.openStream())); apiOutput = ina.readLine(); ina.close(); } catch (IOException e) { @@ -90,50 +86,42 @@ public class UpdateController implements Runnable { LOGGER.error("could not check update version", e); }); } - - if (useBeta) { - JsonArray objectArray = Json.parse("{\"items\": " + apiOutput + "}").asObject().get("items").asArray(); - JsonValue object = objectArray.get(0); - JsonArray objectAssets = object.asObject().get("assets").asArray(); - - updateBuildNumber = object.asObject().getString("tag_name", ""); -// updateName = object.asObject().getString("name", ""); -// updateChanges = object.asObject().getString("body", ""); - - for (JsonValue asset : objectAssets) { - browserDownloadUrl = asset.asObject().getString("browser_download_url", ""); - } - - } else { - JsonObject object = Json.parse(apiOutput).asObject(); - JsonArray objectAssets = Json.parse(apiOutput).asObject().get("assets").asArray(); - - updateBuildNumber = object.getString("tag_name", ""); -// updateName = object.getString("name", ""); -// updateChanges = object.getString("body", ""); - for (JsonValue asset : objectAssets) { - browserDownloadUrl = asset.asObject().getString("browser_download_url", ""); - + + JsonArray objectArray = Json.parse("{\"items\": " + apiOutput + "}").asObject().get("items").asArray(); + JsonValue object = objectArray.get(0).asObject(); // set to the latest release as default + JsonObject objectAsset = object.asObject().get("assets").asArray().get(0).asObject(); + + for(JsonValue objectIt : objectArray) { + // TODO note this will download still the pre-release if there's a more recent stable version + if(objectIt.asObject().getBoolean("prerelease", false) == useBeta) { + // we found the needed release either beta or not + object = objectIt; + objectAsset = objectIt.asObject().get("assets").asArray().get(0).asObject(); + break; } } + + updateBuildNumber = Integer.parseInt(object.asObject().getString("tag_name", "")); + updateName = object.asObject().getString("name", ""); + updateChanges = object.asObject().getString("body", ""); LOGGER.info("Build: " + buildNumber + ", Update: " + updateBuildNumber); - // Compares the program BuildNumber with the current BuildNumber if program - // BuildNumber < current BuildNumber then perform a update - int iversion = Integer.parseInt(buildNumber); - int iaktVersion = Integer.parseInt(updateBuildNumber.replace(".", "")); - - if (iversion >= iaktVersion) { + /** + * Compare the program BuildNumber with the current BuildNumber + * if buildNumber < updateBuildNumber then perform a update + */ + if (buildNumber >= updateBuildNumber) { Platform.runLater(() -> { - mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnNoUpdateAvailable")); + mainWindowController.getUpdateBtn().setText(XMLController.getLocalBundle().getString("updateBtnNoUpdateAvailable")); }); LOGGER.info("no update available"); } else { Platform.runLater(() -> { - mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnUpdateAvailable")); + mainWindowController.getUpdateBtn().setText(XMLController.getLocalBundle().getString("updateBtnUpdateAvailable")); }); LOGGER.info("update available"); + browserDownloadUrl = objectAsset.getString("browser_download_url", ""); LOGGER.info("download link: " + browserDownloadUrl); try { // open new Http connection, ProgressMonitorInputStream for downloading the data @@ -148,7 +136,7 @@ public class UpdateController implements Runnable { org.apache.commons.io.FileUtils.copyFile(new File("cemu_UI_update.jar"), new File("cemu_UI.jar")); org.apache.commons.io.FileUtils.deleteQuietly(new File("cemu_UI_update.jar")); // delete update new ProcessBuilder("java", "-jar", "cemu_UI.jar").start(); // start the new application - System.exit(0); // finishes itself + System.exit(0); // close the current application } catch (IOException e) { Platform.runLater(() -> { LOGGER.info("could not download update files", e); diff --git a/src/main/java/com/cemu_UI/controller/XMLController.java b/src/main/java/com/cemu_UI/controller/XMLController.java new file mode 100644 index 0000000..f0bc0d5 --- /dev/null +++ b/src/main/java/com/cemu_UI/controller/XMLController.java @@ -0,0 +1,419 @@ +/** + * cemu_UI + * + * Copyright 2017-2019 <@Seil0> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package com.cemu_UI.controller; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Locale; +import java.util.Properties; +import java.util.ResourceBundle; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.cemu_UI.datatypes.GlobalDataTypes.CloudService; + +public class XMLController { + + private static final String userHome = System.getProperty("user.home"); + private static final String userName = System.getProperty("user.name"); + private static final String osName = System.getProperty("os.name"); + private static final String osArch = System.getProperty("os.arch"); + private static final String osVers = System.getProperty("os.version"); + private static final String javaVers = System.getProperty("java.version"); + private static final String javaVend = System.getProperty("java.vendor"); + private static final String sysLocal = System.getProperty("user.language") + "_" + System.getProperty("user.country"); + private static String dirCemuUIPath; + private static File dirCemuUI; + private static File configFile; + private static File gamesDBFile; + private static File reference_gamesFile; + private static File pictureCache; + + // user settings + private static String color = "00a8cc"; + private static String usrLocal = sysLocal; + private static boolean autoUpdate = false; + private static boolean useBeta = false; + private static boolean fullscreen = false; + private static boolean cloudSync = false; + private static ResourceBundle localBundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US); + + private static String cemuPath; + private static String romDirectoryPath; + private static String folderID; + private static CloudService cloudService; + private static long lastLocalSync; + private static double windowWidth; + private static double windowHeight; + + + private static final Logger LOGGER = LogManager.getLogger(XMLController.class.getName()); + private Properties props = new Properties(); + + public XMLController() { + + if (osName.contains("Windows")) { + dirCemuUIPath = userHome + "/Documents/cemu_UI"; + } else { + dirCemuUIPath = userHome + "/cemu_UI"; + } + + // set the concrete files + dirCemuUI = new File(dirCemuUIPath); + configFile = new File(dirCemuUI + "/config.xml"); + gamesDBFile = new File(dirCemuUI + "/games.db"); + reference_gamesFile = new File(dirCemuUI + "/reference_games.db"); + pictureCache= new File(dirCemuUI+"/picture_cache"); + } + + /** + * save settings to the config.xml file + */ + public void saveSettings() { + LOGGER.info("saving Settings ..."); + + try { + props.setProperty("cemuPath", getCemuPath()); + props.setProperty("romPath", getRomDirectoryPath()); + props.setProperty("color", getColor()); + props.setProperty("language", getUsrLocal()); + props.setProperty("fullscreen", String.valueOf(isFullscreen())); + props.setProperty("cloudSync", String.valueOf(isCloudSync())); + props.setProperty("autoUpdate", String.valueOf(isAutoUpdate())); + props.setProperty("useBeta", String.valueOf(isUseBeta())); + if (getCloudService() == null) { + props.setProperty("cloudService", ""); + props.setProperty("folderID", ""); + props.setProperty("lastLocalSync", ""); + } else { + props.setProperty("cloudService", getCloudService().toString()); + props.setProperty("folderID", getFolderID()); + props.setProperty("lastLocalSync", Long.toString(getLastLocalSync())); + } + + props.setProperty("windowWidth", Double.toString(getWindowWidth())); + props.setProperty("windowHeight", Double.toString(getWindowHeight())); + + OutputStream outputStream = new FileOutputStream(XMLController.getConfigFile()); // new output-stream + props.storeToXML(outputStream, "cemu_UI settings"); // write new .xml + outputStream.close(); + LOGGER.info("saving Settings done!"); + } catch (IOException e) { + LOGGER.error("an error occured", e); + } + } + + /** + * loading saved settings from the config.xml file + * if a value is not present, default is used instead + */ + public void loadSettings() { + LOGGER.info("loading settings ..."); + try { + InputStream inputStream = new FileInputStream(XMLController.getConfigFile()); + props.loadFromXML(inputStream); // new input-stream from .xml + + try { + setCemuPath(props.getProperty("cemuPath")); + } catch (Exception e) { + LOGGER.error("cloud not load cemuPath", e); + setCemuPath(""); + } + + try { + setRomDirectoryPath(props.getProperty("romPath")); + } catch (Exception e) { + LOGGER.error("could not load romPath", e); + setRomDirectoryPath(""); + } + + try { + setColor(props.getProperty("color")); + } catch (Exception e) { + LOGGER.error("could not load color value, setting default instead", e); + setColor("00a8cc"); + } + + if (props.getProperty("language") == null) { + LOGGER.error("cloud not load language, setting default instead"); + setUsrLocal("en_US"); + } else { + setUsrLocal(props.getProperty("language")); + } + + try { + setFullscreen(Boolean.parseBoolean(props.getProperty("fullscreen"))); + } catch (Exception e) { + LOGGER.error("could not load fullscreen, setting default instead", e); + setFullscreen(false); + } + + try { + setCloudSync(Boolean.parseBoolean(props.getProperty("cloudSync"))); + } catch (Exception e) { + LOGGER.error("could not load cloudSync, setting default instead", e); + setCloudSync(false); + } + + try { + setAutoUpdate(Boolean.parseBoolean(props.getProperty("autoUpdate"))); + } catch (Exception e) { + LOGGER.error("cloud not load autoUpdate", e); + setAutoUpdate(false); + } + + try { + setUseBeta(Boolean.parseBoolean(props.getProperty("useBeta"))); + } catch (Exception e) { + LOGGER.error("cloud not load autoUpdate", e); + setUseBeta(false); + } + + try { + switch (props.getProperty("cloudService")) { + case "GoogleDrive": + setCloudService(CloudService.GoogleDrive); + break; + case "Dropbox": + setCloudService(CloudService.Dropbox); + break; + default: + break; + } + } catch (Exception e) { + LOGGER.error("could not load cloudSync", e); + setCloudService(null); + } + + try { + setFolderID(props.getProperty("folderID")); + } catch (Exception e) { + LOGGER.error("could not load folderID, disable cloud sync. Please contact an developer", e); + setCloudSync(false); + } + + try { + setLastLocalSync(Long.parseLong(props.getProperty("lastLocalSync"))); + } catch (Exception e) { + LOGGER.error("could not load lastSuccessSync, setting default instead", e); + setLastLocalSync(0); + } + + try { + setWindowWidth(Double.parseDouble(props.getProperty("windowWidth"))); + } catch (Exception e) { + LOGGER.error("could not load windowWidth, setting default instead", e); + setWindowWidth(904); + } + + try { + setWindowHeight(Double.parseDouble(props.getProperty("windowHeight"))); + } catch (Exception e) { + LOGGER.error("could not load windowHeight, setting default instead", e); + setWindowHeight(600); + } + + inputStream.close(); + LOGGER.info("loading settings done!"); + } catch (IOException e) { + LOGGER.error("an error occured", e); + } + } + + // getters for application variables + + public static String getUserHome() { + return userHome; + } + + public static String getUserName() { + return userName; + } + + public static String getOsName() { + return osName; + } + + public static String getOsArch() { + return osArch; + } + + public static String getOsVers() { + return osVers; + } + + public static String getJavaVers() { + return javaVers; + } + + public static String getJavaVend() { + return javaVend; + } + + public static String getSysLocal() { + return sysLocal; + } + + public static String getDirCemuUIPath() { + return dirCemuUIPath; + } + + public static File getDirCemuUI() { + return dirCemuUI; + } + + public static File getConfigFile() { + return configFile; + } + + public static File getGamesDBFile() { + return gamesDBFile; + } + + public static File getRference_gamesFile() { + return reference_gamesFile; + } + + public static File getPictureCache() { + return pictureCache; + } + + // getters & setters for user settings + + public static String getColor() { + return color; + } + + public static void setColor(String color) { + XMLController.color = color; + } + + public static String getUsrLocal() { + return usrLocal; + } + + public static void setUsrLocal(String usrLocal) { + XMLController.usrLocal = usrLocal; + } + + public static boolean isAutoUpdate() { + return autoUpdate; + } + + public static void setAutoUpdate(boolean autoUpdate) { + XMLController.autoUpdate = autoUpdate; + } + + public static boolean isUseBeta() { + return useBeta; + } + + public static void setUseBeta(boolean useBeta) { + XMLController.useBeta = useBeta; + } + + public static boolean isFullscreen() { + return fullscreen; + } + + public static void setFullscreen(boolean fullscreen) { + XMLController.fullscreen = fullscreen; + } + + public static boolean isCloudSync() { + return cloudSync; + } + + public static void setCloudSync(boolean cloudSync) { + XMLController.cloudSync = cloudSync; + } + + public static ResourceBundle getLocalBundle() { + return localBundle; + } + + public static void setLocalBundle(ResourceBundle localBundle) { + XMLController.localBundle = localBundle; + } + + public static String getCemuPath() { + return cemuPath; + } + + public static void setCemuPath(String cemuPath) { + XMLController.cemuPath = cemuPath; + } + + public static String getRomDirectoryPath() { + return romDirectoryPath; + } + + public static void setRomDirectoryPath(String romDirectoryPath) { + XMLController.romDirectoryPath = romDirectoryPath; + } + + + public static String getFolderID() { + return folderID; + } + + public static void setFolderID(String folderID) { + XMLController.folderID = folderID; + } + + public static CloudService getCloudService() { + return cloudService; + } + + public static void setCloudService(CloudService cloudService) { + XMLController.cloudService = cloudService; + } + + public static long getLastLocalSync() { + return lastLocalSync; + } + + public static void setLastLocalSync(long lastLocalSync) { + XMLController.lastLocalSync = lastLocalSync; + } + + public static double getWindowWidth() { + return windowWidth; + } + + public static void setWindowWidth(double windowWidth) { + XMLController.windowWidth = windowWidth; + } + + public static double getWindowHeight() { + return windowHeight; + } + + public static void setWindowHeight(double windowHeight) { + XMLController.windowHeight = windowHeight; + } +} diff --git a/src/main/java/com/cemu_UI/datatypes/CourseTableDataType.java b/src/main/java/com/cemu_UI/datatypes/CourseTableDataType.java index f1f79f1..da923d9 100644 --- a/src/main/java/com/cemu_UI/datatypes/CourseTableDataType.java +++ b/src/main/java/com/cemu_UI/datatypes/CourseTableDataType.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.datatypes; import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject; diff --git a/src/main/java/com/cemu_UI/datatypes/GlobalDataTypes.java b/src/main/java/com/cemu_UI/datatypes/GlobalDataTypes.java new file mode 100644 index 0000000..d259223 --- /dev/null +++ b/src/main/java/com/cemu_UI/datatypes/GlobalDataTypes.java @@ -0,0 +1,29 @@ +/** + * cemu_UI + * + * Copyright 2017-2019 <@Seil0> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package com.cemu_UI.datatypes; + +public class GlobalDataTypes { + + public enum CloudService { + GoogleDrive, Dropbox + } +} diff --git a/src/main/java/com/cemu_UI/datatypes/SmmdbApiDataType.java b/src/main/java/com/cemu_UI/datatypes/SmmdbApiDataType.java index 749fa3a..8a1f17a 100644 --- a/src/main/java/com/cemu_UI/datatypes/SmmdbApiDataType.java +++ b/src/main/java/com/cemu_UI/datatypes/SmmdbApiDataType.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.datatypes; import javafx.beans.property.IntegerProperty; diff --git a/src/main/java/com/cemu_UI/datatypes/UIROMDataType.java b/src/main/java/com/cemu_UI/datatypes/UIROMDataType.java index 2a66c6e..66e2f4a 100644 --- a/src/main/java/com/cemu_UI/datatypes/UIROMDataType.java +++ b/src/main/java/com/cemu_UI/datatypes/UIROMDataType.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017-2018 <@Seil0> + * Copyright 2017-2019 <@Seil0> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,109 +18,114 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ + package com.cemu_UI.datatypes; +import java.io.File; + import com.jfoenix.controls.JFXButton; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; +import javafx.geometry.Insets; +import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; -public class UIROMDataType { +public class UIROMDataType extends VBox { + + private String romPath; + private String titleID; + private String name; + private Label label = new Label(); + private JFXButton button = new JFXButton(); + private ImageView imageView = new ImageView(); + + public UIROMDataType(String romPath, String titleID, String name, String coverPath) { + this(); + + this.romPath = romPath; + this.titleID = titleID; + this.name = name; + + label.setText(name); + imageView.setImage(new Image(new File(coverPath).toURI().toString())); + } + + public UIROMDataType(String romPath, String titleID, String name, String coverPath, ContextMenu contextMenu) { + this(); + + this.romPath = romPath; + this.titleID = titleID; + this.name = name; + + label.setText(name); + imageView.setImage(new Image(new File(coverPath).toURI().toString())); + button.setContextMenu(contextMenu); + } + + public UIROMDataType() { + super.getChildren().addAll(label, button); + + label.setMaxWidth(200); + label.setPadding(new Insets(0,0,0,8)); + label.setFont(Font.font("System", FontWeight.BOLD, 14)); + + imageView.setFitHeight(300); + imageView.setFitWidth(200); + + button.setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 3); "); + button.setGraphic(imageView); + } - private final SimpleObjectProperty vBox = new SimpleObjectProperty<>(); - private final SimpleObjectProperty