Compare commits

...

8 Commits

Author SHA1 Message Date
Maschell 0add2f26cf Bump version 2024-04-27 11:15:22 +02:00
Maschell 7c3097a785 Update Dockerfile 2024-04-27 11:15:22 +02:00
Maschell 19cf4ecd5f Bump softprops/action-gh-release from 1 to 2 2024-04-27 11:15:22 +02:00
Maschell 69c645bbee Bump actions/checkout from 3 to 4 2024-04-27 11:15:22 +02:00
Maschell 10743f784c Fix the update notification 2024-04-27 11:15:22 +02:00
Maschell ae56c04b7c More cleanup and fixes 2024-04-27 11:15:22 +02:00
Maschell 2078522898 Fix config menu 2024-04-27 11:15:22 +02:00
Maschell 85288e1bf5 WUPS 0.8.0 support 2024-04-27 11:15:22 +02:00
10 changed files with 240 additions and 172 deletions

View File

@ -9,7 +9,7 @@ jobs:
clang-format:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src --exclude ./src/utils/json.hpp
@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-22.04
needs: clang-format
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: create version.h
run: |
git_hash=$(git rev-parse --short "$GITHUB_SHA")
@ -48,7 +48,7 @@ jobs:
- name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.wps
- name: Create Release
uses: "softprops/action-gh-release@v1"
uses: "softprops/action-gh-release@v2"
with:
tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
draft: false

View File

@ -6,7 +6,7 @@ jobs:
clang-format:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src --exclude ./src/utils/json.hpp
@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-22.04
needs: clang-format
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: create version.h
run: |
git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ sysapp.cbp
.idea/
cmake-build-debug/
CMakeLists.txt
*.zip

View File

@ -1,8 +1,8 @@
FROM ghcr.io/wiiu-env/devkitppc:20230621
FROM ghcr.io/wiiu-env/devkitppc:20240423
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20230719 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/librpxloader:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20240425 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/librpxloader:20240425 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libcurlwrapper:20230715 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libsdutils:20230621 /artifacts $DEVKITPRO

View File

@ -5,11 +5,15 @@
#include <notifications/notification_defines.h>
#include <notifications/notifications.h>
#include <sdutils/sdutils.h>
#include <sys/fcntl.h>
#include <sys/unistd.h>
#include <thread>
std::unique_ptr<std::thread> sShowHintThread;
static bool sShutdownHintThread = false;
bool SaveHintShownToStorage(bool hintShown);
void ShowHints() {
bool isOverlayReady = false;
while (!sShutdownHintThread &&
@ -29,7 +33,7 @@ void ShowHints() {
const char *tmp_file = "fs:/vol/external01/wiiu/write_lock";
int fd = -1;
if ((fd = open(tmp_file, O_CREAT | O_TRUNC | O_RDWR)) < 0) {
DEBUG_FUNCTION_LINE_VERBOSE("SD Card mounted but not writable");
DEBUG_FUNCTION_LINE_WARN("SD Card mounted but not writable. errno: %d", errno);
NotificationModuleStatus err;
NMColor red = {237, 28, 36, 255};
NotificationModuleHandle outHandle;
@ -50,20 +54,31 @@ void ShowHints() {
NotificationModuleStatus err;
if ((err = NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 15.0f)) == NOTIFICATION_MODULE_RESULT_SUCCESS &&
(err = NotificationModule_AddInfoNotification("Tip: You can open a configuration menu by pressing \ue052 + \ue07A + \ue046")) == NOTIFICATION_MODULE_RESULT_SUCCESS) {
if (WUPS_OpenStorage() == WUPS_STORAGE_ERROR_SUCCESS) {
gConfigMenuHintShown = true;
wups_storage_item_t *cat_other = nullptr;
if (WUPS_GetSubItem(nullptr, CAT_OTHER, &cat_other) == WUPS_STORAGE_ERROR_SUCCESS) {
WUPS_StoreInt(cat_other, CONFIG_MENU_HINT_SHOWN_ID, gConfigMenuHintShown);
}
WUPS_CloseStorage();
}
gConfigMenuHintShown = true;
SaveHintShownToStorage(gConfigMenuHintShown);
} else {
DEBUG_FUNCTION_LINE_ERR("Failed to show Notification: %d %s", err, NotificationModule_GetStatusStr(err));
}
}
}
bool SaveHintShownToStorage(bool hintShown) {
WUPSStorageError storageError;
auto subItem = WUPSStorageAPI::GetSubItem(CAT_OTHER, storageError);
if (!subItem) {
DEBUG_FUNCTION_LINE_ERR("Failed to get sub category");
return false;
}
storageError = subItem->Store(CONFIG_MENU_HINT_SHOWN_ID, hintShown);
if (storageError != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store hint shown");
return false;
}
return WUPSStorageAPI::SaveStorage() == WUPS_STORAGE_ERROR_SUCCESS;
}
void StartHintThread() {
sShowHintThread.reset();
sShutdownHintThread = false;

View File

@ -11,14 +11,17 @@
#include <padscore/wpad.h>
#include <rpxloader/rpxloader.h>
#include <string>
#include <sys/stat.h>
#include <thread>
#include <vpad/input.h>
#include <wups/function_patching.h>
static NotificationModuleHandle sAromaUpdateHandle = 0;
std::unique_ptr<std::thread> sCheckUpdateThread;
static bool sShutdownUpdateThread = false;
void UpdateCheckThreadEntry();
void ShowUpdateNotification();
constexpr uint32_t HIDE_UPDATE_WARNING_VPAD_COMBO = VPAD_BUTTON_MINUS;
constexpr uint32_t LAUNCH_AROMA_UPDATER_VPAD_COMBO = VPAD_BUTTON_PLUS;
constexpr uint32_t sHoldForFramesTarget = 60;
@ -41,6 +44,26 @@ void StopUpdaterCheckThread() {
}
}
bool saveLatestUpdateHash(const std::string &hash) {
WUPSStorageError err;
auto subItem = WUPSStorageAPI::GetSubItem(CAT_OTHER, err);
if (!subItem) {
DEBUG_FUNCTION_LINE_ERR("Failed to get sub category");
return false;
}
if (subItem->Store(LAST_UPDATE_HASH_ID, hash) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store latest update hash");
return false;
}
if (WUPSStorageAPI::SaveStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to save storage");
return false;
}
return true;
}
void UpdateCheckThreadEntry() {
bool isOverlayReady = false;
while (!sShutdownUpdateThread &&
@ -57,45 +80,46 @@ void UpdateCheckThreadEntry() {
std::string errorTextOut;
float progress;
if (DownloadUtils::DownloadFileToBuffer(AROMA_UPDATER_LAST_UPDATE_URL, outBuffer, responseCodeOut, errorOut, errorTextOut, &progress) == 0) {
try {
AromaUpdater::LatestVersion data = nlohmann::json::parse(outBuffer);
gUpdateChecked = true;
if (gLastHash.empty()) { // don't show update warning on first boot
gLastHash = data.getHash();
} else if (gLastHash != data.getHash()) {
struct stat st {};
if (stat(AROMA_UPDATER_PATH_FULL, &st) >= 0 && S_ISREG(st.st_mode)) {
NotificationModuleStatus err;
if ((err = NotificationModule_AddDynamicNotification("A new Aroma Update is available. "
"Hold \ue045 to launch the Aroma Updater, press \ue046 to hide this message",
&sAromaUpdateHandle)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to add update notification. %s", NotificationModule_GetStatusStr(err));
sAromaUpdateHandle = 0;
}
} else {
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 15.0f);
NotificationModule_AddInfoNotification("A new Aroma Update is available. Please launch the Aroma Updater!");
}
if (DownloadUtils::DownloadFileToBuffer(AROMA_UPDATER_LAST_UPDATE_URL, outBuffer, responseCodeOut, errorOut, errorTextOut, &progress) != 0) {
DEBUG_FUNCTION_LINE_INFO("Download failed: %d %s", errorOut, errorTextOut.c_str());
return;
}
try {
AromaUpdater::LatestVersion data = nlohmann::json::parse(outBuffer);
gUpdateChecked = true;
gLastHash = data.getHash();
} else {
DEBUG_FUNCTION_LINE_VERBOSE("We don't need to update the hash");
return;
}
if (gLastHash.empty()) { // don't show update warning on first boot
gLastHash = data.getHash();
} else if (gLastHash != data.getHash()) {
ShowUpdateNotification();
} else if (gLastHash == data.getHash()) {
DEBUG_FUNCTION_LINE_VERBOSE("We don't need to update the hash");
return;
}
if (WUPS_OpenStorage() == WUPS_STORAGE_ERROR_SUCCESS) {
wups_storage_item_t *cat_other = nullptr;
if (WUPS_GetSubItem(nullptr, CAT_OTHER, &cat_other) == WUPS_STORAGE_ERROR_SUCCESS) {
WUPS_StoreString(cat_other, LAST_UPDATE_HASH_ID, gLastHash.c_str());
}
WUPS_CloseStorage();
}
} catch (std::exception &e) {
DEBUG_FUNCTION_LINE_WARN("Failed to parse AromaUpdater::LatestVersion");
// Update hash
gLastHash = data.getHash();
saveLatestUpdateHash(gLastHash);
} catch (std::exception &e) {
DEBUG_FUNCTION_LINE_WARN("Failed to parse AromaUpdater::LatestVersion");
}
}
void ShowUpdateNotification() {
struct stat st {};
// Check if the Aroma Updater is on the sd card
if (stat(AROMA_UPDATER_PATH_FULL, &st) >= 0 && S_ISREG(st.st_mode)) {
NotificationModuleStatus err;
if ((err = NotificationModule_AddDynamicNotification("A new Aroma Update is available. "
"Hold \ue045 to launch the Aroma Updater, press \ue046 to hide this message",
&sAromaUpdateHandle)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to add update notification. %s", NotificationModule_GetStatusStr(err));
sAromaUpdateHandle = 0;
}
} else {
DEBUG_FUNCTION_LINE_INFO("Download failed: %d %s", errorOut, errorTextOut.c_str());
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 15.0f);
NotificationModule_AddInfoNotification("A new Aroma Update is available. Please launch the Aroma Updater!");
}
}
@ -158,6 +182,7 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan,
static uint32_t sWPADLastButtonHold[4] = {0, 0, 0, 0};
static uint32_t sHoldForXFramesWPAD[4] = {0, 0, 0, 0};
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
real_WPADRead(chan, data);
if (!sAromaUpdateHandle) {

View File

@ -13,7 +13,7 @@
#include <utils/logger.h>
#include <wups.h>
WUPS_PLUGIN_NAME("AromaBasePlugin");
WUPS_PLUGIN_NAME("Aroma Base Plugin");
WUPS_PLUGIN_DESCRIPTION("Implements small patches and checks for Aroma updates.");
WUPS_PLUGIN_VERSION(PLUGIN_VERSION_FULL);
WUPS_PLUGIN_AUTHOR("Maschell");
@ -22,7 +22,54 @@ WUPS_PLUGIN_LICENSE("GPL");
WUPS_USE_WUT_DEVOPTAB();
WUPS_USE_STORAGE("aroma_base_plugin"); // Unique id for the storage api
static bool sSDUtilsInitDone = false;
bool InitConfigValuesFromStorage() {
bool result = true;
WUPSStorageError storageError;
auto subItemConfig = WUPSStorageAPI::GetOrCreateSubItem(CAT_CONFIG, storageError);
if (!subItemConfig) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create sub category \"%s\"", CAT_CONFIG);
result = false;
} else {
if (subItemConfig->GetOrStoreDefault(USTEALTH_CONFIG_ID, gActivateUStealth, ACTIVATE_USTEALTH_DEFAULT) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\"", USTEALTH_CONFIG_ID);
result = false;
}
if (subItemConfig->GetOrStoreDefault(POWEROFFWARNING_CONFIG_ID, gSkip4SecondOffStatusCheck, SKIP_4_SECOND_OFF_STATUS_CHECK_DEFAULT) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\"", POWEROFFWARNING_CONFIG_ID);
result = false;
}
if (subItemConfig->GetOrStoreDefault(FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID, gForceNDMSuspendSuccess, FORCE_NDM_SUSPEND_SUCCESS_DEFAULT) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\"", FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID);
result = false;
}
if (subItemConfig->GetOrStoreDefault(ALLOW_ERROR_NOTIFICATIONS, gAllowErrorNotifications, ALLOW_ERROR_NOTIFICATIONS_DEFAULT) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\"", ALLOW_ERROR_NOTIFICATIONS);
result = false;
}
}
auto subItemOther = WUPSStorageAPI::GetOrCreateSubItem(CAT_OTHER, storageError);
if (!subItemOther) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create sub category \"%s\"", CAT_OTHER);
result = false;
} else {
if ((storageError = subItemOther->GetOrStoreDefault(CONFIG_MENU_HINT_SHOWN_ID, gConfigMenuHintShown, CONFIG_MENU_HINT_SHOWN_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s", CONFIG_MENU_HINT_SHOWN_ID, WUPSStorageAPI_GetStatusStr(storageError));
result = false;
}
if ((storageError = subItemOther->GetOrStoreDefault(LAST_UPDATE_HASH_ID, gLastHash, LAST_UPDATE_HASH_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s", LAST_UPDATE_HASH_ID, WUPSStorageAPI_GetStatusStr(storageError));
result = false;
}
}
if (WUPSStorageAPI::SaveStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to save storage");
result = false;
}
return result;
}
INITIALIZE_PLUGIN() {
initLogging();
@ -36,45 +83,9 @@ INITIALIZE_PLUGIN() {
DEBUG_FUNCTION_LINE_ERR("SDUtils_InitLibrary failed");
}
// Open storage to read values
WUPSStorageError storageRes = WUPS_OpenStorage();
if (storageRes == WUPS_STORAGE_ERROR_SUCCESS) {
wups_storage_item_t *cat_config = nullptr;
if (WUPS_GetSubItem(nullptr, CAT_CONFIG, &cat_config) == WUPS_STORAGE_ERROR_NOT_FOUND) {
if (WUPS_CreateSubItem(nullptr, CAT_CONFIG, &cat_config) != WUPS_STORAGE_ERROR_SUCCESS) {
cat_config = nullptr;
}
}
InitConfigValuesFromStorage();
if (cat_config != nullptr) {
LOAD_BOOL_FROM_STORAGE(cat_config, USTEALTH_CONFIG_ID, gActivateUStealth);
LOAD_BOOL_FROM_STORAGE(cat_config, POWEROFFWARNING_CONFIG_ID, gSkip4SecondOffStatusCheck);
LOAD_BOOL_FROM_STORAGE(cat_config, FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID, gForceNDMSuspendSuccess);
LOAD_BOOL_FROM_STORAGE(cat_config, ALLOW_ERROR_NOTIFICATIONS, gAllowErrorNotifications);
}
wups_storage_item_t *cat_other = nullptr;
if (WUPS_GetSubItem(nullptr, CAT_OTHER, &cat_other) != WUPS_STORAGE_ERROR_SUCCESS) {
if (WUPS_CreateSubItem(nullptr, CAT_OTHER, &cat_other) != WUPS_STORAGE_ERROR_SUCCESS) {
cat_other = nullptr;
}
}
if (cat_other != nullptr) {
LOAD_BOOL_FROM_STORAGE(cat_other, CONFIG_MENU_HINT_SHOWN_ID, gConfigMenuHintShown);
char hash[41];
memset(hash, 0, sizeof(hash));
LOAD_STRING_FROM_STORAGE(cat_other, LAST_UPDATE_HASH_ID, hash, sizeof(hash));
gLastHash = hash;
}
// Close storage
if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to close storage");
}
} else {
DEBUG_FUNCTION_LINE_ERR("Failed to open storage %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes);
}
InitConfigMenu();
}
ON_APPLICATION_START() {
@ -92,6 +103,7 @@ ON_APPLICATION_START() {
ON_APPLICATION_ENDS() {
StopHintThread();
StopUpdaterCheckThread();
DownloadUtils::Deinit();
deinitLogging();
}

View File

@ -1,5 +1,5 @@
#pragma once
#include "version.h"
#define PLUGIN_VERSION "v0.1.3"
#define PLUGIN_VERSION "v0.1.4"
#define PLUGIN_VERSION_FULL PLUGIN_VERSION PLUGIN_VERSION_EXTRA

View File

@ -1,52 +1,88 @@
#include "config.h"
bool gActivateUStealth = false;
bool gSkip4SecondOffStatusCheck = true;
bool gConfigMenuHintShown = false;
bool gUpdateChecked = false;
bool gForceNDMSuspendSuccess = true;
bool gAllowErrorNotifications = true;
std::string gLastHash = {};
bool gActivateUStealth = ACTIVATE_USTEALTH_DEFAULT;
bool gSkip4SecondOffStatusCheck = SKIP_4_SECOND_OFF_STATUS_CHECK_DEFAULT;
bool gConfigMenuHintShown = CONFIG_MENU_HINT_SHOWN_DEFAULT;
bool gUpdateChecked = UPDATE_CHECKED_DEFAULT;
bool gForceNDMSuspendSuccess = FORCE_NDM_SUSPEND_SUCCESS_DEFAULT;
bool gAllowErrorNotifications = ALLOW_ERROR_NOTIFICATIONS_DEFAULT;
std::string gLastHash = LAST_UPDATE_HASH_DEFAULT;
void boolItemChangedConfig(ConfigItemBoolean *item, bool newValue) {
wups_storage_item_t *cat_config;
if (WUPS_GetSubItem(nullptr, CAT_CONFIG, &cat_config) == WUPS_STORAGE_ERROR_SUCCESS) {
PROCESS_BOOL_ITEM_CHANGED(cat_config, USTEALTH_CONFIG_ID, gActivateUStealth);
PROCESS_BOOL_ITEM_CHANGED(cat_config, POWEROFFWARNING_CONFIG_ID, gSkip4SecondOffStatusCheck);
PROCESS_BOOL_ITEM_CHANGED(cat_config, FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID, gForceNDMSuspendSuccess);
PROCESS_BOOL_ITEM_CHANGED(cat_config, ALLOW_ERROR_NOTIFICATIONS, gAllowErrorNotifications);
WUPSStorageError storageError;
auto subItemConfig = WUPSStorageAPI::GetSubItem(CAT_CONFIG, storageError);
if (!subItemConfig) {
DEBUG_FUNCTION_LINE_ERR("Failed to get sub item \"%s\": %s", CAT_CONFIG, WUPSStorageAPI::GetStatusStr(storageError).data());
return;
}
if (std::string_view(USTEALTH_CONFIG_ID) == item->identifier) {
gActivateUStealth = newValue;
storageError = subItemConfig->Store(USTEALTH_CONFIG_ID, newValue);
} else if (std::string_view(POWEROFFWARNING_CONFIG_ID) == item->identifier) {
gSkip4SecondOffStatusCheck = newValue;
storageError = subItemConfig->Store(POWEROFFWARNING_CONFIG_ID, newValue);
} else if (std::string_view(ALLOW_ERROR_NOTIFICATIONS) == item->identifier) {
gAllowErrorNotifications = newValue;
storageError = subItemConfig->Store(ALLOW_ERROR_NOTIFICATIONS, newValue);
} else if (std::string_view(FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID) == item->identifier) {
gForceNDMSuspendSuccess = newValue;
storageError = subItemConfig->Store(FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID, newValue);
} else {
DEBUG_FUNCTION_LINE_ERR("Failed to get sub item: %s", CAT_CONFIG);
return;
}
if (storageError != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store %s. New value was %d", item->identifier, newValue);
}
}
WUPS_GET_CONFIG() {
// We open the storage, so we can persist the configuration the user did.
if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE("Failed to open storage");
return 0;
WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle) {
try {
WUPSConfigCategory root = WUPSConfigCategory(rootHandle);
auto menuPatches = WUPSConfigCategory::Create("Wii U Menu patches");
menuPatches.add(WUPSConfigItemBoolean::Create(USTEALTH_CONFIG_ID,
"Avoid \"Format\" dialog on Wii U Menu",
ACTIVATE_USTEALTH_DEFAULT, gActivateUStealth,
&boolItemChangedConfig));
menuPatches.add(WUPSConfigItemBoolean::Create(POWEROFFWARNING_CONFIG_ID,
"Skip \"Shutdown warning\" on boot",
SKIP_4_SECOND_OFF_STATUS_CHECK_DEFAULT, gSkip4SecondOffStatusCheck,
&boolItemChangedConfig));
root.add(std::move(menuPatches));
auto otherPatches = WUPSConfigCategory::Create("Other patches");
otherPatches.add(WUPSConfigItemBoolean::Create(ALLOW_ERROR_NOTIFICATIONS,
"Allow error notifications",
ALLOW_ERROR_NOTIFICATIONS_DEFAULT, gAllowErrorNotifications,
&boolItemChangedConfig));
otherPatches.add(WUPSConfigItemBoolean::Create(FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID,
"Fix connecting to a 3DS in Mii Maker",
FORCE_NDM_SUSPEND_SUCCESS_DEFAULT, gForceNDMSuspendSuccess,
&boolItemChangedConfig));
root.add(std::move(otherPatches));
} catch (std::exception &e) {
DEBUG_FUNCTION_LINE_ERR("Exception: %s\n", e.what());
return WUPSCONFIG_API_CALLBACK_RESULT_ERROR;
}
WUPSConfigHandle config;
WUPSConfig_CreateHandled(&config, "Aroma Base Plugin");
WUPSConfigCategoryHandle cat;
WUPSConfig_AddCategoryByNameHandled(config, "Wii U Menu patches", &cat);
WUPSConfigCategoryHandle catOther;
WUPSConfig_AddCategoryByNameHandled(config, "Other patches", &catOther);
WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, USTEALTH_CONFIG_ID, "Avoid \"Format\" dialog on Wii U Menu", gActivateUStealth, &boolItemChangedConfig);
WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, POWEROFFWARNING_CONFIG_ID, "Skip \"Shutdown warning\" on boot", gSkip4SecondOffStatusCheck, &boolItemChangedConfig);
WUPSConfigItemBoolean_AddToCategoryHandled(config, catOther, ALLOW_ERROR_NOTIFICATIONS, "Allow error notifications", gAllowErrorNotifications, &boolItemChangedConfig);
WUPSConfigItemBoolean_AddToCategoryHandled(config, catOther, FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID, "Fix connecting to a 3DS in Mii Maker", gForceNDMSuspendSuccess, &boolItemChangedConfig);
return config;
return WUPSCONFIG_API_CALLBACK_RESULT_SUCCESS;
}
WUPS_CONFIG_CLOSED() {
// Save all changes
if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to close storage");
void ConfigMenuClosedCallback() {
WUPSStorageError storageError;
if ((storageError = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to save storage: %d %s", storageError, WUPSStorageAPI_GetStatusStr(storageError));
}
}
void InitConfigMenu() {
WUPSConfigAPIOptionsV1 configOptions = {.name = "Aroma Base Plugin"};
if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init config api");
}
}

View File

@ -4,46 +4,23 @@
#include <wups/config/WUPSConfigItemBoolean.h>
#include <wups/storage.h>
#define CAT_CONFIG "config"
#define CAT_OTHER "other"
#define CAT_CONFIG "config"
#define CAT_OTHER "other"
#define USTEALTH_CONFIG_ID "ustealth"
#define POWEROFFWARNING_CONFIG_ID "SkipPowerOffWarning"
#define FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID "forceNDMSuspendSuccess"
#define ALLOW_ERROR_NOTIFICATIONS "allowErrorNotifications"
#define USTEALTH_CONFIG_ID "ustealth"
#define POWEROFFWARNING_CONFIG_ID "SkipPowerOffWarning"
#define FORCE_NDM_SUSPEND_SUCCESS_CONFIG_ID "forceNDMSuspendSuccess"
#define ALLOW_ERROR_NOTIFICATIONS "allowErrorNotifications"
#define CONFIG_MENU_HINT_SHOWN_ID "configMenuHintShown"
#define LAST_UPDATE_HASH_ID "lastUpdateHash"
#define CONFIG_MENU_HINT_SHOWN_ID "configMenuHintShown"
#define LAST_UPDATE_HASH_ID "lastUpdateHash"
#define LOAD_BOOL_FROM_STORAGE(__cat, config_name, __variable__) \
if ((storageRes = WUPS_GetBool(__cat, config_name, &__variable__)) == WUPS_STORAGE_ERROR_NOT_FOUND) { \
if (WUPS_StoreBool(__cat, config_name, __variable__) != WUPS_STORAGE_ERROR_SUCCESS) { \
DEBUG_FUNCTION_LINE_WARN("Failed to store bool %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); \
} \
} else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { \
DEBUG_FUNCTION_LINE_WARN("Failed to get bool %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); \
} \
while (0)
#define LOAD_STRING_FROM_STORAGE(__cat, config_name, __string, __string_length) \
if ((storageRes = WUPS_GetString(__cat, config_name, __string, __string_length)) == WUPS_STORAGE_ERROR_NOT_FOUND) { \
if (WUPS_StoreString(__cat, config_name, __string) != WUPS_STORAGE_ERROR_SUCCESS) { \
DEBUG_FUNCTION_LINE_WARN("Failed to store string %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); \
} \
} else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { \
DEBUG_FUNCTION_LINE_WARN("Failed to get bool %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); \
} \
while (0)
#define PROCESS_BOOL_ITEM_CHANGED(cat, __config__name, __variable__) \
if (std::string_view(item->configId) == __config__name) { \
DEBUG_FUNCTION_LINE_ERR("New value in %s: %d", __config__name, newValue); \
__variable__ = newValue; \
WUPS_StoreInt(cat, __config__name, __variable__); \
return; \
} \
while (0)
#define ACTIVATE_USTEALTH_DEFAULT false
#define SKIP_4_SECOND_OFF_STATUS_CHECK_DEFAULT true
#define CONFIG_MENU_HINT_SHOWN_DEFAULT false
#define UPDATE_CHECKED_DEFAULT false
#define FORCE_NDM_SUSPEND_SUCCESS_DEFAULT true
#define ALLOW_ERROR_NOTIFICATIONS_DEFAULT true
#define LAST_UPDATE_HASH_DEFAULT std::string()
extern bool gActivateUStealth;
extern bool gSkip4SecondOffStatusCheck;
@ -51,4 +28,6 @@ extern bool gConfigMenuHintShown;
extern std::string gLastHash;
extern bool gUpdateChecked;
extern bool gForceNDMSuspendSuccess;
extern bool gAllowErrorNotifications;
extern bool gAllowErrorNotifications;
void InitConfigMenu();