From 7958373394bb6574cb09f67a535d481e49ef1ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20L=C3=B3pez=20Guimaraes?= Date: Tue, 29 Oct 2024 18:24:13 +0000 Subject: [PATCH] feat: Improvements in module exports Add new `Inkay_GetStatus` which can be used for retrieving the status of the module. Also add better handling of module initialization, and show a notification from the plugin if the module can't be found. --- plugin/src/main.cpp | 1 + plugin/src/module.cpp | 37 +++++++++++++++++++++++++++++++++---- plugin/src/module.h | 10 ++++++++++ src/config.cpp | 2 ++ src/config.h | 4 ++++ src/export.h | 25 +++++++++++++++++++++++++ src/main.cpp | 31 ++++++++++++++++++++++++++++++- 7 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 src/export.h diff --git a/plugin/src/main.cpp b/plugin/src/main.cpp index 5cb5b19..dfb4ba6 100644 --- a/plugin/src/main.cpp +++ b/plugin/src/main.cpp @@ -77,6 +77,7 @@ INITIALIZE_PLUGIN() { } DEINITIALIZE_PLUGIN() { + Inkay_Finalize(); NotificationModule_DeInitLibrary(); WHBLogCafeDeinit(); diff --git a/plugin/src/module.cpp b/plugin/src/module.cpp index 6a201fa..4e3fb8e 100644 --- a/plugin/src/module.cpp +++ b/plugin/src/module.cpp @@ -14,25 +14,54 @@ along with this program. If not, see . */ +#include "module.h" #include +#include "Notification.h" #include "utils/logger.h" +static OSDynLoad_Module module; +static void (*moduleInitialize)(bool) = nullptr; +static InkayStatus (*moduleGetStatus)() = nullptr; + void Inkay_Initialize(bool apply_patches) { - OSDynLoad_Module module; - void (*moduleInitialize)(bool) = nullptr; + if (module) { + return; + } if (OSDynLoad_Acquire("inkay", &module) != OS_DYNLOAD_OK) { DEBUG_FUNCTION_LINE("Failed to acquire module"); + ShowNotification("Cannot find Inkay module. Ensure the Inkay module is properly installed"); return; } if (OSDynLoad_FindExport(module, OS_DYNLOAD_EXPORT_FUNC, "Inkay_Initialize", reinterpret_cast(&moduleInitialize)) != OS_DYNLOAD_OK) { DEBUG_FUNCTION_LINE("Failed to find initialization function"); + ShowNotification("Cannot find Inkay module initialization function. Ensure the Inkay module is properly installed"); + OSDynLoad_Release(module); return; } moduleInitialize(apply_patches); - - OSDynLoad_Release(module); +} + +void Inkay_Finalize() { + if (module) { + OSDynLoad_Release(module); + moduleInitialize = nullptr; + moduleGetStatus = nullptr; + } +} + +InkayStatus Inkay_GetStatus() { + if (!module) { + return InkayStatus::Error; + } + + if (!moduleGetStatus && OSDynLoad_FindExport(module, OS_DYNLOAD_EXPORT_FUNC, "Inkay_GetStatus", reinterpret_cast(&moduleGetStatus)) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE("Failed to find status function"); + return InkayStatus::Error; + } + + return moduleGetStatus(); } diff --git a/plugin/src/module.h b/plugin/src/module.h index 3da8b0a..b6247a4 100644 --- a/plugin/src/module.h +++ b/plugin/src/module.h @@ -16,4 +16,14 @@ #pragma once +enum class InkayStatus { + Uninitialized, ///< The module isn't initialized + Nintendo, ///< The module is initialized but hasn't applied any patches + Pretendo, ///< The module is initialized and has applied the Pretendo patches + + Error = -1 ///< Failed to retrieve the module status +}; + void Inkay_Initialize(bool apply_patches); +void Inkay_Finalize(); +InkayStatus Inkay_GetStatus(); diff --git a/src/config.cpp b/src/config.cpp index 4923515..67519c8 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -18,6 +18,8 @@ #include "config.h" bool Config::connect_to_network = false; +bool Config::initialized = false; +bool Config::shown_uninitialized_warning = false; static config_strings strings; diff --git a/src/config.h b/src/config.h index 99b2bdc..b816876 100644 --- a/src/config.h +++ b/src/config.h @@ -11,6 +11,10 @@ class Config { public: static bool connect_to_network; + + static bool initialized; + + static bool shown_uninitialized_warning; }; struct config_strings { diff --git a/src/export.h b/src/export.h new file mode 100644 index 0000000..ecc7d99 --- /dev/null +++ b/src/export.h @@ -0,0 +1,25 @@ +/* Copyright 2024 Pretendo Network contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +enum class InkayStatus { + Uninitialized, ///< The module isn't initialized + Nintendo, ///< The module is initialized but hasn't applied any patches + Pretendo, ///< The module is initialized and has applied the Pretendo patches + + Error = -1 ///< Failed to retrieve the module status +}; diff --git a/src/main.cpp b/src/main.cpp index c3bf833..0d2c066 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "export.h" #include "iosu_url_patches.h" #include "config.h" #include "Notification.h" @@ -60,7 +61,9 @@ WUMS_MODULE_VERSION(INKAY_VERSION); WUMS_MODULE_AUTHOR("Pretendo contributors"); WUMS_MODULE_LICENSE("GPLv3"); -WUPS_USE_STORAGE("inkay"); +WUMS_DEPENDS_ON(homebrew_functionpatcher); +WUMS_DEPENDS_ON(homebrew_kernel); +WUMS_DEPENDS_ON(homebrew_notifications); WUMS_USE_WUT_DEVOPTAB(); @@ -114,7 +117,21 @@ static const char *get_pretendo_message() { return get_config_strings(get_system_language()).using_pretendo_network.data(); } +static InkayStatus Inkay_GetStatus() { + if (!Config::initialized) + return InkayStatus::Uninitialized; + + if (Config::connect_to_network) { + return InkayStatus::Pretendo; + } else { + return InkayStatus::Nintendo; + } +} + static void Inkay_Initialize(bool apply_patches) { + if (Config::initialized) + return; + // if using pretendo then (try to) apply the ssl patches if (apply_patches) { Config::connect_to_network = true; @@ -135,10 +152,12 @@ static void Inkay_Initialize(bool apply_patches) { DEBUG_FUNCTION_LINE_VERBOSE("Pretendo URL and NoSSL patches applied successfully."); ShowNotification(get_pretendo_message()); + Config::initialized = true; } else { DEBUG_FUNCTION_LINE_VERBOSE("Pretendo URL and NoSSL patches skipped."); ShowNotification(get_nintendo_network_message()); + Config::initialized = true; return; } @@ -186,6 +205,15 @@ WUMS_DEINITIALIZE() { WUMS_APPLICATION_STARTS() { DEBUG_FUNCTION_LINE_VERBOSE("Inkay " INKAY_VERSION " starting up...\n"); + // TODO - Add a way to reliably check this. We can't do it here since this path gets triggered before + // the plugin gets initialized. + // + // if (!Config::initialized && !Config::shown_uninitialized_warning) { + // DEBUG_FUNCTION_LINE("Inkay module not initialized"); + // ShowNotification("Inkay module was not initialized. Ensure you have the Inkay plugin loaded"); + // Config::shown_uninitialized_warning = true; + // } + setup_olv_libs(); peertopeer_patch(); matchmaking_notify_titleswitch(); @@ -200,3 +228,4 @@ WUMS_APPLICATION_ENDS() { } WUMS_EXPORT_FUNCTION(Inkay_Initialize); +WUMS_EXPORT_FUNCTION(Inkay_GetStatus);