Skip to content

Commit

Permalink
Finalize in-app backup mechanic
Browse files Browse the repository at this point in the history
  • Loading branch information
Nightkingale committed Apr 13, 2024
1 parent 4f76ffc commit dfd23fc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 51 deletions.
95 changes: 61 additions & 34 deletions source/backup.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <filesystem>
#include <fstream>
#include <iostream>

Expand All @@ -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();
Expand All @@ -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);
}

Expand All @@ -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);
Expand All @@ -77,6 +81,7 @@ void backupAccount() {
WHBLogConsoleSetColor(0x99000000);
WHBLogPrint("Error allocating memory!");
WHBLogConsoleDraw();
OSSleepTicks(OSMillisecondsToTicks(5000));
}
else {
WHBLogPrint("Memory was allocated successfully.");
Expand All @@ -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();
}
}
Expand Down
14 changes: 6 additions & 8 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -113,7 +111,7 @@ int main() {
}
}
}

// Deinitialize the program and exit.
deinitialize();
return 0;
}
12 changes: 9 additions & 3 deletions source/switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand Down
11 changes: 5 additions & 6 deletions source/unlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<char>(inFile)), std::istreambuf_iterator<char>());
inFile.close();
WHBLogPrint("System account.dat file read in memory.");
WHBLogConsoleDraw();

// Process each line in the string.
std::istringstream iss(fileContents);
std::string line;
Expand All @@ -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();
Expand Down

0 comments on commit dfd23fc

Please sign in to comment.