diff --git a/source/backup.cpp b/source/backup.cpp index df3ab30..f9236f0 100644 --- a/source/backup.cpp +++ b/source/backup.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -17,30 +18,31 @@ #include "../include/global.h" +bool backupConfirm = false; + void writeBackup(FILE* account, const std::string& backupPath, char* buffer) { + // Create the directories if they don't exist. + std::filesystem::path dirPath = std::filesystem::path(backupPath).remove_filename(); + std::filesystem::create_directories(dirPath); + // Open the backup file for writing. FILE *backup = fopen(backupPath.c_str(), "wb"); if (backup == NULL) { WHBLogConsoleSetColor(0x99000000); - WHBLogPrintf("Error opening backup file.", backupPath.c_str()); + WHBLogPrintf("Error opening backup file."); + WHBLogPrintf("%s", backupPath.c_str()); WHBLogConsoleDraw(); return; } - + // Print the backup path to the screen. WHBLogPrintf("%s", backupPath.c_str()); WHBLogConsoleDraw(); - // Open the backup file and write the account data to it. + rewind(account); // Move the file pointer to the beginning. size_t bytesRead = 0; while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, account)) > 0) { - size_t written = fwrite(buffer, 1, bytesRead, backup); - if (written != bytesRead) { - WHBLogConsoleSetColor(0x99000000); - WHBLogPrintf("Error writing to backup file.", backupPath.c_str()); - WHBLogConsoleDraw(); - return; - } + fwrite(buffer, 1, bytesRead, backup); } - + // Close the backup file. fclose(backup); WHBLogPrintf("Backup account.dat written.", backupPath); WHBLogConsoleDraw(); @@ -50,6 +52,7 @@ void writeBackup(FILE* account, const std::string& backupPath, char* buffer) { WHBLogPrint("The account.dat was backed up successfully!"); WHBLogPrint("The main menu will apppear in 5 seconds..."); WHBLogConsoleDraw(); + WHBLogPrint("---------------------------------------------------------"); fclose(backup); } @@ -59,6 +62,7 @@ void backupAccount() { WHBLogPrint("---------------------------------------------------------"); WHBLogConsoleDraw(); // Check if the account.dat file exists. + std::string backupPath; FILE *account = fopen(ACCOUNT_FILE.c_str(), "rb"); if (account == NULL) { WHBLogConsoleSetColor(0x99000000); @@ -77,6 +81,7 @@ void backupAccount() { WHBLogConsoleSetColor(0x99000000); WHBLogPrint("Error allocating memory!"); WHBLogConsoleDraw(); + OSSleepTicks(OSMillisecondsToTicks(5000)); } else { WHBLogPrint("Memory was allocated successfully."); @@ -85,47 +90,69 @@ void backupAccount() { size_t bytesRead = 0; while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, account)) > 0) { content.append(buffer, bytesRead); - std::string backupPath; WHBLogPrint("account.dat file read in memory."); WHBLogConsoleDraw(); - if (content.find("nintendo") != std::string::npos) { + bool networkAccountFound = false; + if (content.find("account.nintendo.net") != std::string::npos) { backupPath = NNID_BACKUP; WHBLogPrint("Nintendo Network ID detected."); WHBLogConsoleDraw(); + networkAccountFound = true; } - else { + else if (content.find("pretendo-cdn.b-cdn.net") != std::string::npos){ backupPath = PNID_BACKUP; WHBLogPrint("Pretendo Network ID detected."); WHBLogConsoleDraw(); + networkAccountFound = true; } - // Check if the backup file exists. - WHBLogPrintf("Opening backup account.dat for writing.", backupPath.c_str()); - WHBLogConsoleDraw(); - std::ifstream ifile(backupPath); - if (ifile) { - printOverwriteMenu(backupPath.c_str()); + else { + WHBLogConsoleSetColor(0x99000000); + WHBLogPrint("Network ID detection failed!"); + WHBLogPrint("Is this user a local-only account?"); + WHBLogConsoleDraw(); + // Wait 5 seconds, then go back to the menu. + OSSleepTicks(OSMillisecondsToTicks(5000)); + } + if (networkAccountFound) { + // Check if the backup file exists. + WHBLogPrintf("Opening backup account.dat for writing.", backupPath.c_str()); + WHBLogConsoleDraw(); + std::ifstream ifile(backupPath); + if (ifile) { + printOverwriteMenu(backupPath.c_str()); - VPADStatus input; - VPADReadError error; + VPADStatus input; + VPADReadError error; + backupConfirm = false; - while (WHBProcIsRunning()) { - VPADRead(VPAD_CHAN_0, &input, 1, &error); - if (input.trigger == VPAD_BUTTON_A) { - writeBackup(account, backupPath, buffer); - break; - } - else if (input.trigger == VPAD_BUTTON_B) { - break; + while (WHBProcIsRunning()) { + VPADRead(VPAD_CHAN_0, &input, 1, &error); + if (input.trigger == VPAD_BUTTON_A) { + backupConfirm = true; + break; + } + else if (input.trigger == VPAD_BUTTON_B) { + break; + } } } + else { + backupConfirm = true; + } } - else { - writeBackup(account, backupPath, buffer); - } } + // Write the backup file. + if (backupConfirm) { + writeBackup(account, backupPath, buffer); + } + // Close the account.dat file. fclose(account); free(buffer); - OSSleepTicks(OSMillisecondsToTicks(5000)); + // Wait 5 seconds, then go back to the menu. + if (backupConfirm) { + OSSleepTicks(OSMillisecondsToTicks(5000)); + } + // Print the main menu to the screen. printMainMenu(); } } diff --git a/source/main.cpp b/source/main.cpp index b63a606..9f449d0 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -18,7 +18,6 @@ const char* INKAY_CONFIG = "/vol/external01/wiiu/environments/aroma/plugins/config/inkay.json"; const int BUFFER_SIZE = 0x2000; - unsigned int USER_ID; std::string NNID_BACKUP; std::string PNID_BACKUP; @@ -48,29 +47,28 @@ void initialize() { } // Mount the storage device differently depending on Tiramisu or Aroma. Mocha_MountFS("storage_mlc", NULL, "/vol/storage_mlc01"); - + // Grab the user's Mii name and persistent ID. nn::act::Initialize(); int16_t miiName[256]; nn::act::GetMiiName(miiName); MII_NICKNAME = std::string(miiName, miiName + sizeof(miiName) / sizeof(miiName[0])); USER_ID = nn::act::GetPersistentId(); - + // Set the account file path. char user_id_hex[9]; sprintf(user_id_hex, "%08x", USER_ID); ACCOUNT_FILE = "storage_mlc:/usr/save/system/act/" + std::string(user_id_hex) + "/account.dat"; - + // Set the backup file paths. NNID_BACKUP = "/vol/external01/wiiu/accounts/" + std::string(user_id_hex) + "/nnid_account.dat"; PNID_BACKUP = "/vol/external01/wiiu/accounts/" + std::string(user_id_hex) + "/pnid_account.dat"; } int main() { initialize(); - + // Initialize variables for the Wii U GamePad. VPADStatus input; VPADReadError error; - + // Print the main menu to the screen. printMainMenu(); - while (WHBProcIsRunning()) { // Watch the Wii U GamePad for button presses. VPADRead(VPAD_CHAN_0, &input, 1, &error); @@ -113,7 +111,7 @@ int main() { } } } - + // Deinitialize the program and exit. deinitialize(); return 0; } \ No newline at end of file diff --git a/source/switch.cpp b/source/switch.cpp index a556a89..a49989c 100644 --- a/source/switch.cpp +++ b/source/switch.cpp @@ -16,6 +16,7 @@ void switchAccount(const char* backupFile, const char* accountType) { + WHBLogConsoleSetColor(0x00009900); WHBLogPrintf("Switch: You will be swapped to a %s.", accountType); WHBLogPrint("---------------------------------------------------------"); WHBLogConsoleDraw(); @@ -27,12 +28,13 @@ void switchAccount(const char* backupFile, const char* accountType) { if (backup == NULL) { WHBLogConsoleSetColor(0x99000000); WHBLogPrintf("Error opening %s account backup!", accountType); - WHBLogConsoleDraw(); WHBLogPrint("Have you made a backup of this account yet?"); + WHBLogConsoleDraw(); // Wait 5 seconds, then go back to the menu. OSSleepTicks(OSMillisecondsToTicks(5000)); } else { + // Open the account.dat file for writing. WHBLogPrintf("%s account backup opened.", accountType); WHBLogConsoleDraw(); char *buffer = (char *)malloc(BUFFER_SIZE); @@ -64,11 +66,12 @@ void switchAccount(const char* backupFile, const char* accountType) { FILE *inkay = fopen(INKAY_CONFIG, "wb"); if (inkay == NULL) { // If we can't open the file, we will move on. - WHBLogPrint("Error opening Inkay config file!"); + WHBLogPrint("The Inkay config file wasn't found!"); WHBLogPrint("Network will not be automatically swapped."); WHBLogConsoleDraw(); } else { + // Write the network configuration to the file. WHBLogPrint("Inkay config file opened."); WHBLogConsoleDraw(); WHBLogPrintf("Swapping network to %s.", accountType); @@ -83,11 +86,14 @@ void switchAccount(const char* backupFile, const char* accountType) { WHBLogPrint("The account.dat was restored successfully!"); WHBLogPrint("Your console will restart in 5 seconds..."); WHBLogConsoleDraw(); + WHBLogPrint("---------------------------------------------------------"); } - free(buffer); } + // Free the buffer and close the backup file. + free(buffer); fclose(backup); OSSleepTicks(OSMillisecondsToTicks(5000)); + // Soft reset the console. OSForceFullRelaunch(); SYSLaunchMenu(); deinitialize(); diff --git a/source/unlink.cpp b/source/unlink.cpp index eb9cff7..640a1bc 100644 --- a/source/unlink.cpp +++ b/source/unlink.cpp @@ -58,18 +58,17 @@ void unlinkAccount() { {"MiiImageLastModifiedDate", "Sat, 01 Jan 2000 00:00:00 GMT"}, {"IsCommitted", "1"} }; - + // Inform the user that the unlink process has started. + WHBLogConsoleSetColor(0x00009900); WHBLogPrintf("Unlinking: Default settings will be applied."); WHBLogPrint("---------------------------------------------------------"); WHBLogConsoleDraw(); - // Read the entire file into a string. std::ifstream inFile(ACCOUNT_FILE); std::string fileContents((std::istreambuf_iterator(inFile)), std::istreambuf_iterator()); inFile.close(); WHBLogPrint("System account.dat file read in memory."); WHBLogConsoleDraw(); - // Process each line in the string. std::istringstream iss(fileContents); std::string line; @@ -85,20 +84,20 @@ void unlinkAccount() { } WHBLogPrint("Account file in memory patched."); WHBLogConsoleDraw(); - // Write the string back to the file. std::ofstream outFile(ACCOUNT_FILE); outFile << fileContents; outFile.close(); WHBLogPrint("System account.dat file written."); WHBLogConsoleDraw(); - + // Inform the user that the unlink was successful. WHBLogConsoleSetColor(0x00990000); WHBLogPrint("---------------------------------------------------------"); WHBLogPrint("The account.dat was unlinked successfully!"); WHBLogPrint("Your console will restart in 5 seconds..."); WHBLogConsoleDraw(); - + WHBLogPrint("---------------------------------------------------------"); + // Wait 5 seconds, then soft reboot the console. OSSleepTicks(OSMillisecondsToTicks(5000)); OSForceFullRelaunch(); SYSLaunchMenu();