#include #include #include #include #include #include #include #include #include #include #include #include #include #include #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."); 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) { fwrite(buffer, 1, bytesRead, backup); } // Close the backup file. fclose(backup); WHBLogPrintf("Backup account.dat written.", backupPath); WHBLogConsoleDraw(); // Wait 5 seconds, then go back to the menu. WHBLogConsoleSetColor(0x00990000); WHBLogPrint("---------------------------------------------------------"); WHBLogPrint("The account.dat was backed up successfully!"); WHBLogPrint("The main menu will apppear in 5 seconds..."); WHBLogConsoleDraw(); WHBLogPrint("---------------------------------------------------------"); fclose(backup); } void backupAccount() { WHBLogConsoleSetColor(0x00009900); WHBLogPrintf("Backup: A Network ID backup will be created."); 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); WHBLogPrintf("Error opening system account.dat file!"); WHBLogConsoleDraw(); // Wait 5 seconds, then go back to the menu. OSSleepTicks(OSMillisecondsToTicks(5000)); } else { WHBLogPrintf("System account.dat file opened."); WHBLogConsoleDraw(); std::string content; char *buffer = (char *)malloc(BUFFER_SIZE); if (buffer == NULL) { WHBLogConsoleSetColor(0x99000000); WHBLogPrint("Error allocating memory!"); WHBLogConsoleDraw(); OSSleepTicks(OSMillisecondsToTicks(5000)); } else { WHBLogPrint("Memory was allocated successfully."); WHBLogConsoleDraw(); // Read the entire file into a string. size_t bytesRead = 0; while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, account)) > 0) { content.append(buffer, bytesRead); WHBLogPrint("account.dat file read in memory."); WHBLogConsoleDraw(); bool networkAccountFound = false; if (content.find("account.nintendo.net") != std::string::npos) { backupPath = NNID_BACKUP; WHBLogPrint("Nintendo Network ID detected."); WHBLogConsoleDraw(); networkAccountFound = true; } else if (content.find("pretendo-cdn.b-cdn.net") != std::string::npos){ backupPath = PNID_BACKUP; WHBLogPrint("Pretendo Network ID detected."); WHBLogConsoleDraw(); networkAccountFound = true; } 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; backupConfirm = false; 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; } } } // Write the backup file. if (backupConfirm) { writeBackup(account, backupPath, buffer); } // Close the account.dat file. fclose(account); free(buffer); // Wait 5 seconds, then go back to the menu. if (backupConfirm) { OSSleepTicks(OSMillisecondsToTicks(5000)); } // Print the main menu to the screen. printMainMenu(); } } }