Skip to content
This repository was archived by the owner on Dec 24, 2018. It is now read-only.

Commit cce9d9f

Browse files
committed
Update update system
1 parent 01f998a commit cce9d9f

4 files changed

Lines changed: 198 additions & 60 deletions

File tree

gui/source/download.cpp

Lines changed: 170 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ using std::vector;
2929
const char* JSON_URL = "https://raw.githubusercontent.com/Jolty95/TWLoader-update/master/update.json";
3030
bool updateGUI = false;
3131
bool updateNAND = false;
32+
bool updateNAND_part2 = false;
3233
bool updateNAND_STG2 = false;
3334
bool updateACE_RPG = false;
3435
bool updateGBARUNNER_2 = false;
@@ -37,8 +38,13 @@ bool updateR4 = false;
3738
//bool doCleanInstall = true;
3839

3940
std::string gui_url;
41+
std::string gui_3dsx_url;
42+
std::string gui_smdh_url;
43+
std::string demo_gui_3dsx_url;
44+
std::string demo_gui_smdh_url;
4045
std::string nand_url;
41-
std::string nand_stg2_url;
46+
std::string nand_part2_url;
47+
std::string nand_twld_url;
4248
std::string ace_rpg_url;
4349
std::string gbarunner2_url;
4450
std::string loadcard_dstt_url;
@@ -211,9 +217,22 @@ struct ReadJson {
211217
std::string strvalue2;
212218
std::string strvalue3;
213219
std::string strvalue4;
220+
std::string strvalue5;
221+
std::string strvalue6;
222+
std::string strvalue7;
223+
std::string strvalue8;
214224
};
215225

216-
ReadJson internal_json_reader(json_value* json, json_value* val, std::string str1, std::string str2, std::string str3, std::string str4){
226+
ReadJson internal_json_reader(json_value* json, json_value* val,
227+
std::string str1,
228+
std::string str2,
229+
std::string str3,
230+
std::string str4,
231+
std::string str5,
232+
std::string str6,
233+
std::string str7,
234+
std::string str8)
235+
{
217236
ReadJson rj;
218237
for(u32 i = 0; i < (json->u.object.length -1); i++) {
219238
// Create two variables that will store the values and it size
@@ -229,6 +248,14 @@ ReadJson internal_json_reader(json_value* json, json_value* val, std::string str
229248
rj.strvalue3 = subVal->u.string.ptr;
230249
} else if(strncmp(name, str4.c_str(), nameLen) == 0) {
231250
rj.strvalue4 = subVal->u.string.ptr;
251+
} else if(strncmp(name, str5.c_str(), nameLen) == 0) {
252+
rj.strvalue5 = subVal->u.string.ptr;
253+
} else if(strncmp(name, str6.c_str(), nameLen) == 0) {
254+
rj.strvalue6 = subVal->u.string.ptr;
255+
} else if(strncmp(name, str7.c_str(), nameLen) == 0) {
256+
rj.strvalue7 = subVal->u.string.ptr;
257+
} else if(strncmp(name, str8.c_str(), nameLen) == 0) {
258+
rj.strvalue8 = subVal->u.string.ptr;
232259
}
233260
}
234261
}
@@ -303,50 +330,70 @@ int checkUpdate(void) {
303330
char read_gui_major[3];
304331
char read_gui_minor[3];
305332
char read_gui_micro[3];
306-
333+
307334
char read_nand_major[3];
308335
char read_nand_minor[3];
309336
char read_nand_micro[3];
310337

338+
char read_nandpart2_major[3];
339+
char read_nandpart2_minor[3];
340+
char read_nandpart2_micro[3];
341+
311342
char read_nandstg2_major[3];
312343
char read_nandstg2_minor[3];
313344
char read_nandstg2_micro[3];
314345

315346

316347
// Search in GUI object
317348
json_value* val = json->u.object.values[0].value;
318-
ReadJson result = internal_json_reader(json, val, "latest_major", "latest_minor", "latest_micro", "gui_url");
349+
ReadJson result = internal_json_reader(json, val, "latest_major", "latest_minor", "latest_micro", "gui_url", "gui_3dsx_url", "gui_smdh_url", "demo_gui_3dsx_url", "demo_gui_smdh_url");
319350
strncpy(read_gui_major, result.strvalue1.c_str(), sizeof(read_gui_major));
320351
strncpy(read_gui_minor, result.strvalue2.c_str(), sizeof(read_gui_minor));
321352
strncpy(read_gui_micro, result.strvalue3.c_str(), sizeof(read_gui_micro));
322353
gui_url = result.strvalue4.c_str();
354+
gui_3dsx_url = result.strvalue5.c_str();
355+
gui_smdh_url = result.strvalue6.c_str();
356+
demo_gui_3dsx_url = result.strvalue7.c_str();
357+
demo_gui_smdh_url = result.strvalue8.c_str();
323358

324359
// Search in NAND object.
325360
val = json->u.object.values[1].value;
326-
result = internal_json_reader(json, val, "not_major", "not_minor", "not_micro", "nand_url");
361+
json_value* val2 = val->u.object.values[0].value;
362+
result = internal_json_reader(json, val2, "not_major", "not_minor", "not_micro", "nand_url", "nand_null", "nand_null", "nand_null", "nand_null");
327363
strncpy(read_nand_major, result.strvalue1.c_str(), sizeof(read_nand_major));
328364
strncpy(read_nand_minor, result.strvalue2.c_str(), sizeof(read_nand_minor));
329365
strncpy(read_nand_micro, result.strvalue3.c_str(), sizeof(read_nand_micro));
330366
nand_url = result.strvalue4.c_str();
331367

368+
// Search in NAND (part2) object.
369+
val2 = val->u.object.values[1].value;
370+
result = internal_json_reader(json, val2, "p2_not_major", "p2_not_minor", "p2_not_micro", "nand_part2_url", "part2_null", "part2_null", "part2_null", "part2_null");
371+
strncpy(read_nandpart2_major, result.strvalue1.c_str(), sizeof(read_nandpart2_major));
372+
strncpy(read_nandpart2_minor, result.strvalue2.c_str(), sizeof(read_nandpart2_minor));
373+
strncpy(read_nandpart2_micro, result.strvalue3.c_str(), sizeof(read_nandpart2_micro));
374+
nand_part2_url = result.strvalue4.c_str();
375+
332376
// Search in NAND STG2 object.
333-
val = json->u.object.values[2].value;
334-
result = internal_json_reader(json, val, "not_major", "not_minor", "not_micro", "nand_stg2_url");
377+
val2 = val->u.object.values[2].value;
378+
result = internal_json_reader(json, val2, "twld_not_major", "twld_not_minor", "twld_not_micro", "nand_twld_url", "twld_null", "twld_null", "twld_null", "twld_null");
335379
strncpy(read_nandstg2_major, result.strvalue1.c_str(), sizeof(read_nandstg2_major));
336380
strncpy(read_nandstg2_minor, result.strvalue2.c_str(), sizeof(read_nandstg2_minor));
337381
strncpy(read_nandstg2_micro, result.strvalue3.c_str(), sizeof(read_nandstg2_micro));
338-
nand_stg2_url = result.strvalue4.c_str();
382+
nand_twld_url = result.strvalue4.c_str();
339383

340384
// Store latest and current version of GUI and NAND.
341385
char latestVersion[16];
342386
snprintf(latestVersion, sizeof(latestVersion), "%s.%s.%s", read_gui_major, read_gui_minor, read_gui_micro);
343-
387+
344388
char currentVersion[16];
345389
snprintf(currentVersion, sizeof(currentVersion), "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
346-
390+
347391
char latestNANDVersion[16];
348392
snprintf(latestNANDVersion, sizeof(latestNANDVersion), "%s.%s.%s", read_nand_major, read_nand_minor, read_nand_micro);
349-
393+
394+
char latestNAND2Version[16];
395+
snprintf(latestNAND2Version, sizeof(latestNAND2Version), "%s.%s.%s", read_nandpart2_major, read_nandpart2_minor, read_nandpart2_micro);
396+
350397
char latestNANDSTG2Version[16];
351398
snprintf(latestNANDSTG2Version, sizeof(latestNANDSTG2Version), "%s.%s.%s", read_nandstg2_major, read_nandstg2_minor, read_nandstg2_micro);
352399

@@ -364,6 +411,10 @@ int checkUpdate(void) {
364411
if (logEnabled) LogFM("checkUpdate", "NAND update available.");
365412
updateNAND = true;
366413
}
414+
if(strcmp(latestNAND2Version, currentVersion) > 0) {
415+
if (logEnabled) LogFM("checkUpdate", "NAND (part 2) update available.");
416+
updateNAND_part2 = true;
417+
}
367418
if(strcmp(latestNANDSTG2Version, currentVersion) > 0) {
368419
if (logEnabled) LogFM("checkUpdate", "NAND SD stage update available.");
369420
updateNAND_STG2 = true;
@@ -409,7 +460,7 @@ int checkUpdate(void) {
409460
"\n"
410461
"\n"
411462
"\n"
412-
": Close";
463+
": OK";
413464
renderText(12, 16, 0.5f, 0.5f, false, msg);
414465
sf2d_end_frame();
415466
sf2d_swapbuffers();
@@ -431,9 +482,9 @@ int checkUpdate(void) {
431482
}
432483

433484
// Search in prebuilds object
434-
val = json->u.object.values[3].value;
435-
json_value* val2 = val->u.object.values[0].value;
436-
result = internal_json_reader(json, val2, "ace_rpg_major", "ace_rpg_minor", "ace_rpg_micro", "ace_rpg_url");
485+
val = json->u.object.values[2].value;
486+
val2 = val->u.object.values[0].value;
487+
result = internal_json_reader(json, val2, "ace_rpg_major", "ace_rpg_minor", "ace_rpg_micro", "ace_rpg_url", "ace_rpg_null", "ace_rpg_null", "ace_rpg_null", "ace_rpg_null");
437488
ace_rpg_url = result.strvalue4.c_str();
438489

439490
char ace_rpg_version[16];
@@ -444,7 +495,7 @@ int checkUpdate(void) {
444495
}
445496

446497
val2 = val->u.object.values[1].value;
447-
result = internal_json_reader(json, val2, "GBARunner2_major", "GBARunner2_minor", "GBARunner2_micro", "GBARunner2_url");
498+
result = internal_json_reader(json, val2, "GBARunner2_major", "GBARunner2_minor", "GBARunner2_micro", "GBARunner2_url", "GBARunner2_null", "GBARunner2_null", "GBARunner2_null", "GBARunner2_null");
448499
gbarunner2_url = result.strvalue4.c_str();
449500

450501
char GBARunner2_version[16];
@@ -455,7 +506,7 @@ int checkUpdate(void) {
455506
}
456507

457508
val2 = val->u.object.values[2].value;
458-
result = internal_json_reader(json, val2, "loadcard_dstt_major", "loadcard_dstt_minor", "loadcard_dstt_micro", "loadcard_dstt_url");
509+
result = internal_json_reader(json, val2, "loadcard_dstt_major", "loadcard_dstt_minor", "loadcard_dstt_micro", "loadcard_dstt_url", "loadcard_dstt_null", "loadcard_dstt_null", "loadcard_dstt_null", "loadcard_dstt_null");
459510
loadcard_dstt_url = result.strvalue4.c_str();
460511
char loadcard_dstt_version[16];
461512
snprintf(loadcard_dstt_version, sizeof(loadcard_dstt_version), "%s.%s.%s", result.strvalue1.c_str(), result.strvalue2.c_str(), result.strvalue3.c_str());
@@ -465,7 +516,7 @@ int checkUpdate(void) {
465516
}
466517

467518
val2 = val->u.object.values[3].value;
468-
result = internal_json_reader(json, val2, "r4_major", "r4_minor", "r4_micro", "r4_url");
519+
result = internal_json_reader(json, val2, "r4_major", "r4_minor", "r4_micro", "r4_url", "r4_null", "r4_null", "r4_null", "r4_null");
469520
r4_url = result.strvalue4.c_str();
470521

471522
char r4_version[16];
@@ -539,42 +590,78 @@ void DownloadTWLoaderCIAs(void) {
539590

540591
if(yestoupdate) {
541592
int resGUI = -1;
593+
int resGUI_3DSX = -1;
594+
int resGUI_SMDH = -1;
542595
int resNAND = -1;
596+
int resNAND_part2 = -1;
543597
int resNAND_STG2 = -1;
544598
struct stat st;
545599
if (updateGUI) {
546-
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
547-
if (screenmode == SCREEN_MODE_SETTINGS) {
548-
sf2d_draw_texture(settingstex, 0, 0);
549-
}
550-
sf2d_draw_texture(dialogboxtex, 0, 0);
551-
static const char gui_msg[] =
552-
"Now downloading latest TWLoader version...\n"
553-
"(GUI)\n"
554-
"\n"
555-
"Do not turn off the power.\n";
556-
renderText(12, 16, 0.5f, 0.5f, false, gui_msg);
557-
sf2d_end_frame();
558-
sf2d_swapbuffers();
559-
560-
if(stat("sdmc:/cia",&st) == 0){
561-
// Use root/cia folder instead
562-
resGUI = downloadFile(gui_url.c_str(),"/cia/TWLoader.cia", MEDIA_SD_CIA);
563-
}else{
564-
mkdir("sdmc:/_nds/twloader/cia", 0777); // Use twloader/cia folder instead
565-
resGUI = downloadFile(gui_url.c_str(),"/_nds/twloader/cia/TWLoader.cia", MEDIA_SD_CIA);
566-
}
600+
if (settings.ui.filetype == 0 || settings.ui.filetype == 2) {
601+
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
602+
if (screenmode == SCREEN_MODE_SETTINGS) {
603+
sf2d_draw_texture(settingstex, 0, 0);
604+
}
605+
sf2d_draw_texture(dialogboxtex, 0, 0);
606+
static const char gui_msg[] =
607+
"Now downloading latest TWLoader version...\n"
608+
"(GUI, CIA)\n"
609+
"\n"
610+
"Do not turn off the power.\n";
611+
renderText(12, 16, 0.5f, 0.5f, false, gui_msg);
612+
sf2d_end_frame();
613+
sf2d_swapbuffers();
567614

568-
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
569-
if (screenmode == SCREEN_MODE_SETTINGS) {
570-
sf2d_draw_texture(settingstex, 0, 0);
615+
if(stat("sdmc:/cia",&st) == 0){
616+
// Use root/cia folder instead
617+
resGUI = downloadFile(gui_url.c_str(),"/cia/TWLoader.cia", MEDIA_SD_CIA);
618+
}else{
619+
mkdir("sdmc:/_nds/twloader/cia", 0777); // Use twloader/cia folder instead
620+
resGUI = downloadFile(gui_url.c_str(),"/_nds/twloader/cia/TWLoader.cia", MEDIA_SD_CIA);
621+
}
622+
623+
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
624+
if (screenmode == SCREEN_MODE_SETTINGS) {
625+
sf2d_draw_texture(settingstex, 0, 0);
626+
}
627+
sf2d_draw_texture(dialogboxtex, 0, 0);
628+
}
629+
if (settings.ui.filetype == 1 || settings.ui.filetype == 2) {
630+
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
631+
if (screenmode == SCREEN_MODE_SETTINGS) {
632+
sf2d_draw_texture(settingstex, 0, 0);
633+
}
634+
sf2d_draw_texture(dialogboxtex, 0, 0);
635+
static const char gui_msg[] =
636+
"Now downloading latest TWLoader version...\n"
637+
"(GUI, 3DSX)\n"
638+
"\n"
639+
"Do not turn off the power.\n";
640+
renderText(12, 16, 0.5f, 0.5f, false, gui_msg);
641+
sf2d_end_frame();
642+
sf2d_swapbuffers();
643+
644+
if (isDemo) {
645+
mkdir("sdmc:/3ds/TWLoader_demo", 0777);
646+
resGUI_3DSX = downloadFile(demo_gui_3dsx_url.c_str(),"/3ds/TWLoader_demo/TWLoader_demo.3dsx", MEDIA_SD_FILE);
647+
resGUI_SMDH = downloadFile(demo_gui_smdh_url.c_str(),"/3ds/TWLoader_demo/TWLoader_demo.smdh", MEDIA_SD_FILE);
648+
} else {
649+
mkdir("sdmc:/3ds/TWLoader", 0777);
650+
resGUI_3DSX = downloadFile(gui_3dsx_url.c_str(),"/3ds/TWLoader/TWLoader.3dsx", MEDIA_SD_FILE);
651+
resGUI_SMDH = downloadFile(gui_smdh_url.c_str(),"/3ds/TWLoader/TWLoader.smdh", MEDIA_SD_FILE);
652+
}
653+
654+
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
655+
if (screenmode == SCREEN_MODE_SETTINGS) {
656+
sf2d_draw_texture(settingstex, 0, 0);
657+
}
658+
sf2d_draw_texture(dialogboxtex, 0, 0);
571659
}
572-
sf2d_draw_texture(dialogboxtex, 0, 0);
573660
}
574661
if (resGUI == 0 && updateNAND) {
575662
static const char twlnand_msg[] =
576663
"Now downloading latest TWLoader version...\n"
577-
"(TWLNAND side CIA)\n"
664+
"(TWLNAND side CIA (part 1))\n"
578665
"\n"
579666
"Do not turn off the power.\n";
580667
renderText(12, 16, 0.5f, 0.5f, false, twlnand_msg);
@@ -599,26 +686,60 @@ void DownloadTWLoaderCIAs(void) {
599686
}
600687
sf2d_draw_texture(dialogboxtex, 0, 0);
601688
}
602-
if (updateNAND_STG2) {
689+
if (resNAND == 0 && updateNAND_STG2) {
603690
static const char twlnandstg2_msg[] =
604691
"Now downloading latest TWLoader version...\n"
605-
"(SD stage of TWLNAND side)\n"
692+
"(SD stage of (part 1 of) TWLNAND side)\n"
606693
"\n"
607694
"Do not turn off the power.\n";
608695
renderText(12, 16, 0.5f, 0.5f, false, twlnandstg2_msg);
609696
sf2d_end_frame();
610697
sf2d_swapbuffers();
611698

612-
resNAND_STG2 = downloadFile(nand_stg2_url.c_str(),"/_nds/twloader/TWLD.twldr", MEDIA_SD_FILE);
699+
resNAND_STG2 = downloadFile(nand_twld_url.c_str(),"/_nds/twloader/TWLD.twldr", MEDIA_SD_FILE);
700+
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
701+
if (screenmode == SCREEN_MODE_SETTINGS) {
702+
sf2d_draw_texture(settingstex, 0, 0);
703+
}
704+
sf2d_draw_texture(dialogboxtex, 0, 0);
705+
}
706+
if (resNAND_STG2 == 0 && updateNAND_part2) {
707+
static const char twlnand2_msg[] =
708+
"Now downloading latest TWLoader version...\n"
709+
"(TWLNAND side CIA (part 2))\n"
710+
"\n"
711+
"Do not turn off the power.\n";
712+
renderText(12, 16, 0.5f, 0.5f, false, twlnand2_msg);
713+
sf2d_end_frame();
714+
sf2d_swapbuffers();
715+
// Delete first if installed.
716+
if(checkTWLNANDSide2()){
717+
amInit();
718+
AM_DeleteTitle(MEDIATYPE_NAND, NTRLAUNCHER_TID);
719+
amExit();
720+
}
721+
722+
if(stat("sdmc:/cia",&st) == 0){
723+
// Use root/cia folder instead
724+
resNAND = downloadFile(nand_part2_url.c_str(),"/cia/TWLoader - TWLNAND side (part 2).cia", MEDIA_NAND_CIA);
725+
}else{
726+
resNAND = downloadFile(nand_part2_url.c_str(),"/_nds/twloader/cia/TWLoader - TWLNAND side (part 2).cia", MEDIA_NAND_CIA);
727+
}
613728
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
614729
if (screenmode == SCREEN_MODE_SETTINGS) {
615730
sf2d_draw_texture(settingstex, 0, 0);
616731
}
617732
sf2d_draw_texture(dialogboxtex, 0, 0);
618733
}
619734
// If gui or nand failed, stop before downloading prebuilds.
620-
if(resGUI != 0 || (updateNAND && resNAND != 0) || (updateNAND_STG2 && resNAND_STG2 != 0) ) {
621-
DialogBoxDisappear(12, 16, "Update failed.");
735+
if (settings.ui.filetype == 0 || settings.ui.filetype == 2) {
736+
if(resGUI != 0 || (updateNAND && resNAND != 0) || (updateNAND_STG2 && resNAND_STG2 != 0) || (updateNAND_part2 && resNAND_part2 != 0) ) {
737+
DialogBoxDisappear(12, 16, "Update failed.");
738+
}
739+
} else if (settings.ui.filetype == 1) {
740+
if(resGUI_3DSX != 0 || (updateNAND && resNAND != 0) || (updateNAND_STG2 && resNAND_STG2 != 0) || (updateNAND_part2 && resNAND_part2 != 0) ) {
741+
DialogBoxDisappear(12, 16, "Update failed.");
742+
}
622743
}
623744
if(resGUI == 0 && updateACE_RPG) {
624745
static const char msg[] =

gui/source/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,18 @@ bool checkTWLNANDSide(void) {
12881288
return R_SUCCEEDED(AM_GetTitleInfo(MEDIATYPE_NAND, 1, &tid, &entry));
12891289
}
12901290

1291+
/**
1292+
* Check if the TWLNAND-side (part 2) title is installed or not
1293+
* Title ID: 0x0004800554574C31ULL
1294+
* MediaType: MEDIATYPE_NAND
1295+
* @return: true if installed, false if not
1296+
*/
1297+
bool checkTWLNANDSide2(void) {
1298+
u64 tid = NTRLAUNCHER_TID;
1299+
AM_TitleEntry entry;
1300+
return R_SUCCEEDED(AM_GetTitleInfo(MEDIATYPE_NAND, 1, &tid, &entry));
1301+
}
1302+
12911303
void deletemode_internal(RomLocation location, std::string del_rom) {
12921304
char path[256];
12931305

0 commit comments

Comments
 (0)