mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2026-08-28 05:45:30 -05:00
Add "plugins details" command
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
#include "ShellCommands.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "plugin/ButtonComboManager.h"
|
||||
#include "plugin/FunctionData.h"
|
||||
#include "plugin/HookData.h"
|
||||
#include "plugin/PluginContainer.h"
|
||||
#include "plugin/PluginData.h"
|
||||
#include "plugin/SectionInfo.h"
|
||||
#include "utils/StringTools.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#include <iopshell/api.h>
|
||||
|
||||
@@ -11,7 +17,327 @@
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <zconf.h>
|
||||
|
||||
namespace {
|
||||
std::string toString(WUPSButtonCombo_ComboType type) {
|
||||
switch (type) {
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_INVALID:
|
||||
return "Invalid";
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD:
|
||||
return "Hold";
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD_OBSERVER:
|
||||
return "Hold (Observer)";
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN:
|
||||
return "Press Down";
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN_OBSERVER:
|
||||
return "Press Down (Observer)";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
std::string toString(WUPSButtonCombo_ComboStatus type) {
|
||||
switch (type) {
|
||||
case WUPS_BUTTON_COMBO_COMBO_STATUS_INVALID_STATUS:
|
||||
return "Invalid";
|
||||
case WUPS_BUTTON_COMBO_COMBO_STATUS_VALID:
|
||||
return "Valid";
|
||||
case WUPS_BUTTON_COMBO_COMBO_STATUS_CONFLICT:
|
||||
return "Conflict";
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
|
||||
std::string toString(const function_replacement_library_type_t type) {
|
||||
switch (type) {
|
||||
case LIBRARY_AVM:
|
||||
return "AVM";
|
||||
case LIBRARY_CAMERA:
|
||||
return "CAMERA";
|
||||
case LIBRARY_COREINIT:
|
||||
return "COREINIT";
|
||||
case LIBRARY_DC:
|
||||
return "DC";
|
||||
case LIBRARY_DMAE:
|
||||
return "DMAE";
|
||||
case LIBRARY_DRMAPP:
|
||||
return "DRMAPP";
|
||||
case LIBRARY_ERREULA:
|
||||
return "ERREULA";
|
||||
case LIBRARY_GX2:
|
||||
return "GX2";
|
||||
case LIBRARY_H264:
|
||||
return "H264";
|
||||
case LIBRARY_LZMA920:
|
||||
return "LZMA920";
|
||||
case LIBRARY_MIC:
|
||||
return "MIC";
|
||||
case LIBRARY_NFC:
|
||||
return "NFC";
|
||||
case LIBRARY_NIO_PROF:
|
||||
return "NIO_PROF";
|
||||
case LIBRARY_NLIBCURL:
|
||||
return "NLIBCURL";
|
||||
case LIBRARY_NLIBNSS:
|
||||
return "NLIBNSS";
|
||||
case LIBRARY_NLIBNSS2:
|
||||
return "NLIBNSS2";
|
||||
case LIBRARY_NN_AC:
|
||||
return "NN_AC";
|
||||
case LIBRARY_NN_ACP:
|
||||
return "NN_ACP";
|
||||
case LIBRARY_NN_ACT:
|
||||
return "NN_ACT";
|
||||
case LIBRARY_NN_AOC:
|
||||
return "NN_AOC";
|
||||
case LIBRARY_NN_BOSS:
|
||||
return "NN_BOSS";
|
||||
case LIBRARY_NN_CCR:
|
||||
return "NN_CCR";
|
||||
case LIBRARY_NN_CMPT:
|
||||
return "NN_CMPT";
|
||||
case LIBRARY_NN_DLP:
|
||||
return "NN_DLP";
|
||||
case LIBRARY_NN_EC:
|
||||
return "NN_EC";
|
||||
case LIBRARY_NN_FP:
|
||||
return "NN_FP";
|
||||
case LIBRARY_NN_HAI:
|
||||
return "NN_HAI";
|
||||
case LIBRARY_NN_HPAD:
|
||||
return "NN_HPAD";
|
||||
case LIBRARY_NN_IDBE:
|
||||
return "NN_IDBE";
|
||||
case LIBRARY_NN_NDM:
|
||||
return "NN_NDM";
|
||||
case LIBRARY_NN_NETS2:
|
||||
return "NN_NETS2";
|
||||
case LIBRARY_NN_NFP:
|
||||
return "NN_NFP";
|
||||
case LIBRARY_NN_NIM:
|
||||
return "NN_NIM";
|
||||
case LIBRARY_NN_OLV:
|
||||
return "NN_OLV";
|
||||
case LIBRARY_NN_PDM:
|
||||
return "NN_PDM";
|
||||
case LIBRARY_NN_SAVE:
|
||||
return "NN_SAVE";
|
||||
case LIBRARY_NN_SL:
|
||||
return "NN_SL";
|
||||
case LIBRARY_NN_SPM:
|
||||
return "NN_SPM";
|
||||
case LIBRARY_NN_TEMP:
|
||||
return "NN_TEMP";
|
||||
case LIBRARY_NN_UDS:
|
||||
return "NN_UDS";
|
||||
case LIBRARY_NN_VCTL:
|
||||
return "NN_VCTL";
|
||||
case LIBRARY_NSYSCCR:
|
||||
return "NSYSCCR";
|
||||
case LIBRARY_NSYSHID:
|
||||
return "NSYSHID";
|
||||
case LIBRARY_NSYSKBD:
|
||||
return "NSYSKBD";
|
||||
case LIBRARY_NSYSNET:
|
||||
return "NSYSNET";
|
||||
case LIBRARY_NSYSUHS:
|
||||
return "NSYSUHS";
|
||||
case LIBRARY_NSYSUVD:
|
||||
return "NSYSUVD";
|
||||
case LIBRARY_NTAG:
|
||||
return "NTAG";
|
||||
case LIBRARY_PADSCORE:
|
||||
return "PADSCORE";
|
||||
case LIBRARY_PROC_UI:
|
||||
return "PROC_UI";
|
||||
case LIBRARY_SND_CORE:
|
||||
return "SND_CORE";
|
||||
case LIBRARY_SND_USER:
|
||||
return "SND_USER";
|
||||
case LIBRARY_SNDCORE2:
|
||||
return "SNDCORE2";
|
||||
case LIBRARY_SNDUSER2:
|
||||
return "SNDUSER2";
|
||||
case LIBRARY_SWKBD:
|
||||
return "SWKBD";
|
||||
case LIBRARY_SYSAPP:
|
||||
return "SYSAPP";
|
||||
case LIBRARY_TCL:
|
||||
return "TCL";
|
||||
case LIBRARY_TVE:
|
||||
return "TVE";
|
||||
case LIBRARY_UAC:
|
||||
return "UAC";
|
||||
case LIBRARY_UAC_RPL:
|
||||
return "UAC_RPL";
|
||||
case LIBRARY_USB_MIC:
|
||||
return "USB_MIC";
|
||||
case LIBRARY_UVC:
|
||||
return "UVC";
|
||||
case LIBRARY_UVD:
|
||||
return "UVD";
|
||||
case LIBRARY_VPAD:
|
||||
return "VPAD";
|
||||
case LIBRARY_VPADBASE:
|
||||
return "VPADBASE";
|
||||
case LIBRARY_ZLIB125:
|
||||
return "ZLIB125";
|
||||
case LIBRARY_OTHER:
|
||||
return "OTHER";
|
||||
}
|
||||
return "OTHER";
|
||||
}
|
||||
|
||||
const char *getButtonChar(const WUPSButtonCombo_Buttons value) {
|
||||
std::string combo;
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_A) {
|
||||
return "A";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_B) {
|
||||
return "B";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_X) {
|
||||
return "X";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_Y) {
|
||||
return "Y";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_L) {
|
||||
return "L";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_R) {
|
||||
return "R";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_ZL) {
|
||||
return "ZL";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_ZR) {
|
||||
return "ZR";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_UP) {
|
||||
return "UP";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_DOWN) {
|
||||
return "DOWN";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_LEFT) {
|
||||
return "LEFT";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_RIGHT) {
|
||||
return "RIGHT";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_STICK_L) {
|
||||
return "STICK-L";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_STICK_R) {
|
||||
return "STICK-R";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_PLUS) {
|
||||
return "PLUS";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_MINUS) {
|
||||
return "MINUS";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_TV) {
|
||||
return "TV";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_RESERVED_BIT) {
|
||||
return "RESERVED-BIT";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_1) {
|
||||
return "1";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_2) {
|
||||
return "2";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_C) {
|
||||
return "C";
|
||||
}
|
||||
if (value & WUPS_BUTTON_COMBO_BUTTON_Z) {
|
||||
return "Z";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getComboAsString(const uint32_t value) {
|
||||
char comboString[60] = {};
|
||||
|
||||
for (uint32_t i = 0; i < 32; i++) {
|
||||
uint32_t bitMask = 1 << i;
|
||||
if (value & bitMask) {
|
||||
auto val = getButtonChar(static_cast<WUPSButtonCombo_Buttons>(bitMask));
|
||||
if (val[0] != '\0') {
|
||||
strcat(comboString, val);
|
||||
strcat(comboString, "+");
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string res(comboString);
|
||||
if (res.ends_with("+")) {
|
||||
res.pop_back();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string getMaskAsString(WUPSButtonCombo_ControllerTypes controller_mask) {
|
||||
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_NONE) {
|
||||
return "NONE";
|
||||
}
|
||||
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_ALL) {
|
||||
return "ALL";
|
||||
}
|
||||
// Optional: Check strictly for full groups if you prefer that over listing individual bits
|
||||
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_VPAD) {
|
||||
return "VPAD (All)";
|
||||
}
|
||||
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_WPAD) {
|
||||
return "WPAD (All)";
|
||||
}
|
||||
std::vector<std::string> parts;
|
||||
|
||||
// VPADs
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_VPAD_0) parts.emplace_back("VPAD_0");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_VPAD_1) parts.emplace_back("VPAD_1");
|
||||
|
||||
// WPADs
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_0) parts.emplace_back("WPAD_0");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_1) parts.emplace_back("WPAD_1");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_2) parts.emplace_back("WPAD_2");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_3) parts.emplace_back("WPAD_3");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_4) parts.emplace_back("WPAD_4");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_5) parts.emplace_back("WPAD_5");
|
||||
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_6) parts.emplace_back("WPAD_6");
|
||||
|
||||
|
||||
if (parts.empty()) {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (size_t i = 0; i < parts.size(); ++i) {
|
||||
if (i > 0) {
|
||||
result += " | ";
|
||||
}
|
||||
result += parts[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isHoldCombo(WUPSButtonCombo_ComboType type) {
|
||||
switch (type) {
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD:
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD_OBSERVER:
|
||||
return true;
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_INVALID:
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN:
|
||||
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN_OBSERVER:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
namespace ShellCommands {
|
||||
namespace {
|
||||
class ConsoleTable {
|
||||
@@ -164,7 +490,6 @@ namespace ShellCommands {
|
||||
table.Print();
|
||||
}
|
||||
|
||||
|
||||
void ListPlugins(int argc, char **argv) {
|
||||
bool showAll = false;
|
||||
if (argc > 1 && (std::string_view(argv[1]) == "-a" || std::string_view(argv[1]) == "--all")) {
|
||||
@@ -173,7 +498,7 @@ namespace ShellCommands {
|
||||
|
||||
ConsoleTable table;
|
||||
|
||||
// Define Columns
|
||||
table.AddColumn("Index", ConsoleTable::LEFT);
|
||||
table.AddColumn("Name", ConsoleTable::LEFT);
|
||||
table.AddColumn("Author", ConsoleTable::LEFT);
|
||||
table.AddColumn("Version", ConsoleTable::LEFT);
|
||||
@@ -184,13 +509,15 @@ namespace ShellCommands {
|
||||
table.AddColumn("Memory footprint", ConsoleTable::RIGHT);
|
||||
table.AddColumn("Heap usage", ConsoleTable::RIGHT);
|
||||
uint32_t totalSizeOther = 0;
|
||||
uint32_t id = 0;
|
||||
for (const auto &plugin : gLoadedPlugins) {
|
||||
if (!showAll && !plugin.isLinkedAndLoaded()) {
|
||||
totalSizeOther += plugin.getMemoryFootprint();
|
||||
id++;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto meta = plugin.getMetaInformation();
|
||||
auto &meta = plugin.getMetaInformation();
|
||||
|
||||
std::string heapUsage = "unknown";
|
||||
if (const auto tracking = plugin.getTrackingMemoryAllocator()) {
|
||||
@@ -202,6 +529,7 @@ namespace ShellCommands {
|
||||
}
|
||||
|
||||
std::vector<std::string> rowData;
|
||||
rowData.emplace_back(std::to_string(id));
|
||||
rowData.emplace_back(meta.getName());
|
||||
rowData.emplace_back(meta.getAuthor());
|
||||
rowData.emplace_back(meta.getVersion());
|
||||
@@ -213,6 +541,7 @@ namespace ShellCommands {
|
||||
rowData.emplace_back(heapUsage);
|
||||
|
||||
table.AddRow(rowData);
|
||||
id++;
|
||||
}
|
||||
|
||||
if (totalSizeOther > 0 && !showAll) {
|
||||
@@ -231,12 +560,111 @@ namespace ShellCommands {
|
||||
table.Print();
|
||||
}
|
||||
|
||||
void PluginDetails(std::optional<uint32_t> idOpt) {
|
||||
uint32_t id = 0;
|
||||
for (const auto &plugin : gLoadedPlugins) {
|
||||
if (idOpt) {
|
||||
if (*idOpt != id) {
|
||||
id++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto &meta = plugin.getMetaInformation();
|
||||
OSReport("\n");
|
||||
OSReport("Index: %d\n", id);
|
||||
OSReport("Name: %s\n", meta.getName().c_str());
|
||||
OSReport("Description: %s\n", meta.getDescription().c_str());
|
||||
OSReport("Author: %s\n", meta.getAuthor().c_str());
|
||||
OSReport("Version: %s\n", meta.getVersion().c_str());
|
||||
OSReport("Build date: %s\n", meta.getBuildTimestamp().c_str());
|
||||
OSReport("Storage Id: %s\n", meta.getStorageId().c_str());
|
||||
OSReport("Active: %s\n", plugin.isLinkedAndLoaded() ? "Yes" : "No");
|
||||
OSReport("API: %s\n", meta.getWUPSVersion().toString().c_str());
|
||||
|
||||
const auto memoryFootprint = plugin.getMemoryFootprint();
|
||||
const auto pluginSize = plugin.getPluginDataCopy()->getBuffer().size_bytes();
|
||||
size_t textSize = 0;
|
||||
size_t dataSize = 0;
|
||||
|
||||
OSReport("Memory footprint: ~%s\n", BytesToHumanReadable(memoryFootprint).c_str());
|
||||
OSReport("\t- .wps: ~%s\n", BytesToHumanReadable(pluginSize).c_str());
|
||||
if (plugin.isLinkedAndLoaded()) {
|
||||
textSize = plugin.getPluginLinkInformation().getTextMemory().size();
|
||||
dataSize = plugin.getPluginLinkInformation().getDataMemory().size();
|
||||
OSReport("\t- CODE: ~%s\n", BytesToHumanReadable(textSize).c_str());
|
||||
OSReport("\t- DATA: ~%s\n", BytesToHumanReadable(dataSize).c_str());
|
||||
}
|
||||
const auto otherSize = memoryFootprint - pluginSize - textSize - dataSize;
|
||||
OSReport("\t- Other: ~%s\n", BytesToHumanReadable(otherSize).c_str());
|
||||
OSReport("\n");
|
||||
const auto §ionInfoList = plugin.getPluginLinkInformation().getSectionInfoList();
|
||||
OSReport("Sections: %d\n", sectionInfoList.size());
|
||||
for (const auto §ionInfo : sectionInfoList) {
|
||||
OSReport("\t- 0x%08X - 0x%08X %-15s %-11s\n", sectionInfo.second.getAddress(), sectionInfo.second.getAddress() + sectionInfo.second.getSize(), sectionInfo.first.c_str(), BytesToHumanReadable(sectionInfo.second.getSize()).c_str());
|
||||
}
|
||||
OSReport("\n");
|
||||
|
||||
const auto &hookList = plugin.getPluginLinkInformation().getHookDataList();
|
||||
OSReport("WUPS Hooks: %d\n", hookList.size());
|
||||
for (const auto &hook : hookList) {
|
||||
OSReport("\t- %p - %s\n", hook.getFunctionPointer(), hookNameToString(hook.getType()).c_str());
|
||||
}
|
||||
OSReport("\n");
|
||||
const auto &buttonCombos = plugin.GetButtonComboData();
|
||||
OSReport("Button combos: %d\n", buttonCombos.size());
|
||||
for (const auto &combo : buttonCombos) {
|
||||
OSReport("\t- \"%s\" \n", combo.label.c_str());
|
||||
OSReport("\t\tStatus: %s\n", toString(combo.status).c_str());
|
||||
OSReport("\t\tCallback: %p (%s)\n", combo.callbackOptions.callback, combo.callbackOptions.callback != nullptr ? getModuleAndSymbolName(reinterpret_cast<uint32_t>(combo.callbackOptions.callback)).c_str() : "");
|
||||
OSReport("\t\tContext: %p\n", combo.callbackOptions.context);
|
||||
OSReport("\t\tType: %s\n", toString(combo.buttonComboOptions.type).c_str());
|
||||
if (isHoldCombo(combo.buttonComboOptions.type)) {
|
||||
OSReport("\t\tHold duration: %d\n", combo.buttonComboOptions.optionalHoldForXMs);
|
||||
}
|
||||
OSReport("\t\tCombo: %s\n", getComboAsString(combo.buttonComboOptions.basicCombo.combo).c_str());
|
||||
OSReport("\t\tController Mask: %s\n", getMaskAsString(combo.buttonComboOptions.basicCombo.controllerMask).c_str());
|
||||
}
|
||||
OSReport("\n");
|
||||
const auto &functionPatches = plugin.getPluginLinkInformation().getFunctionDataList();
|
||||
OSReport("Function patches: %d\n", functionPatches.size());
|
||||
for (const auto &function : functionPatches) {
|
||||
if (function.getPhysicalAddress() != nullptr) {
|
||||
OSReport("\t- Hook: %p - PA: %p VA: %p\n", function.getReplaceAddress(), function.getPhysicalAddress(), function.getVirtualAddress());
|
||||
} else {
|
||||
OSReport("\t- Hook: %p - %-9s - %s\n", function.getReplaceAddress(), toString(function.getLibrary()).c_str(), function.getName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
OSReport("\n");
|
||||
OSReport("Heap usage:\n");
|
||||
if (const auto tracking = plugin.getTrackingMemoryAllocator(); tracking != nullptr) {
|
||||
if (const auto stats = tracking->GetHeapMemoryUsageSnapshot(); stats) {
|
||||
OSReport("\t- Currently allocated: %s\n", BytesToHumanReadable(stats->currentAllocated).c_str());
|
||||
OSReport("\t- Peak allocated: %s\n", BytesToHumanReadable(stats->peakAllocated).c_str());
|
||||
OSReport("\t- Current allocations: %d\n", stats->allocationMap.size());
|
||||
OSReport("\t- Total allocations: %d\n", stats->allocCount);
|
||||
OSReport("\t- Total frees: %d\n", stats->freeCount);
|
||||
}
|
||||
} else {
|
||||
OSReport("\t Not tracked.\n");
|
||||
}
|
||||
|
||||
OSReport("\n=================\n");
|
||||
|
||||
id++;
|
||||
if (idOpt) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Init() {
|
||||
sPluginGroup = std::make_unique<IOPShellModule::CommandGroup>("plugins", "Manage aroma plugins");
|
||||
|
||||
sPluginGroup->AddCommand("heap_usage", PrintHeapUsage, "Show current heap usage for tracked plugins");
|
||||
|
||||
sPluginGroup->AddRawCommand("list", ListPlugins, "Lists active plugins", "Usage: \"list -a\" to list all plugins");
|
||||
sPluginGroup->AddCommand("details", PluginDetails, "Shows details for plugins");
|
||||
|
||||
sPluginCmdHandle = sPluginGroup->Register();
|
||||
}
|
||||
|
||||
@@ -598,4 +598,28 @@ WUPSButtonCombo_Error ButtonComboManager::ExecuteForWrapper(const WUPSButtonComb
|
||||
|
||||
uint32_t ButtonComboManager::getHandle() const {
|
||||
return *mHandle;
|
||||
}
|
||||
|
||||
std::vector<ButtonComboInfo> ButtonComboManager::GetButtonCombos() const {
|
||||
std::vector<ButtonComboInfo> result;
|
||||
for (auto &wrapper : mComboWrappers) {
|
||||
ButtonComboInfo res;
|
||||
char text[256] = {};
|
||||
WUPSButtonCombo_MetaOptionsOut meta = {text, sizeof(text)};
|
||||
if (wrapper.GetButtonComboCallback(res.callbackOptions) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
if (wrapper.GetButtonComboInfoEx(res.buttonComboOptions) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
if (wrapper.GetButtonComboMeta(meta) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
if (wrapper.GetButtonComboStatus(res.status) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
res.label = text;
|
||||
result.push_back(res);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -10,12 +10,18 @@
|
||||
|
||||
class ButtonComboWrapper;
|
||||
|
||||
struct ButtonComboInfo {
|
||||
std::string label;
|
||||
WUPSButtonCombo_CallbackOptions callbackOptions;
|
||||
WUPSButtonCombo_ButtonComboInfoEx buttonComboOptions;
|
||||
WUPSButtonCombo_ComboStatus status;
|
||||
};
|
||||
|
||||
class ButtonComboManager {
|
||||
public:
|
||||
explicit ButtonComboManager();
|
||||
~ButtonComboManager();
|
||||
|
||||
|
||||
ButtonComboManager(const ButtonComboManager &) = delete;
|
||||
|
||||
ButtonComboManager(ButtonComboManager &&src) noexcept;
|
||||
@@ -67,6 +73,8 @@ public:
|
||||
|
||||
[[nodiscard]] uint32_t getHandle() const;
|
||||
|
||||
[[nodiscard]] std::vector<ButtonComboInfo> GetButtonCombos() const;
|
||||
|
||||
private:
|
||||
std::forward_list<ButtonComboWrapper> mComboWrappers;
|
||||
std::unique_ptr<uint32_t> mHandle = std::make_unique<uint32_t>();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "PluginContainer.h"
|
||||
|
||||
#include "plugin/ButtonComboManager.h"
|
||||
#include "plugin/FunctionData.h"
|
||||
#include "plugin/HookData.h"
|
||||
#include "plugin/PluginConfigData.h"
|
||||
@@ -8,6 +9,7 @@
|
||||
#include "plugin/RelocationData.h"
|
||||
#include "plugin/SectionInfo.h"
|
||||
|
||||
#include "plugin/ButtonComboManager.h"
|
||||
#include "utils/buttoncombo/ButtonComboUtils.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/storage/StorageUtils.h"
|
||||
@@ -135,6 +137,7 @@ void PluginContainer::InitButtonComboData() {
|
||||
}
|
||||
mButtonComboManagerHandle = ButtonComboUtils::API::Internal::CreateButtonComboData();
|
||||
}
|
||||
|
||||
void PluginContainer::DeinitButtonComboData() {
|
||||
if (getMetaInformation().getWUPSVersion() < WUPSVersion(0, 8, 2)) {
|
||||
return;
|
||||
@@ -142,6 +145,14 @@ void PluginContainer::DeinitButtonComboData() {
|
||||
ButtonComboUtils::API::Internal::RemoveButtonComboData(mButtonComboManagerHandle);
|
||||
}
|
||||
|
||||
|
||||
std::vector<ButtonComboInfo> PluginContainer::GetButtonComboData() const {
|
||||
if (getMetaInformation().getWUPSVersion() < WUPSVersion(0, 8, 2)) {
|
||||
return {};
|
||||
}
|
||||
return ButtonComboUtils::API::Internal::GetButtonComboData(mButtonComboManagerHandle);
|
||||
}
|
||||
|
||||
uint32_t PluginContainer::getButtonComboManagerHandle() const {
|
||||
return mButtonComboManagerHandle;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
|
||||
struct ButtonComboInfo;
|
||||
class PluginData;
|
||||
|
||||
class PluginContainer {
|
||||
@@ -67,6 +69,7 @@ public:
|
||||
|
||||
void InitButtonComboData();
|
||||
void DeinitButtonComboData();
|
||||
std::vector<ButtonComboInfo> GetButtonComboData() const;
|
||||
|
||||
[[nodiscard]] uint32_t getButtonComboManagerHandle() const;
|
||||
|
||||
|
||||
@@ -24,6 +24,16 @@ namespace ButtonComboUtils::API {
|
||||
DEBUG_FUNCTION_LINE_WARN("Tried to remove ButtonComboManager by invalid handle: %08X", buttonComboManagerHandle);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ButtonComboInfo> GetButtonComboData(uint32_t buttonComboManagerHandle) {
|
||||
std::lock_guard lock(sButtonComboMutex);
|
||||
for (auto &manager : sButtonComboManager) {
|
||||
if (manager.getHandle() == buttonComboManagerHandle) {
|
||||
return manager.GetButtonCombos();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
} // namespace Internal
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
#include <wups/button_combo/defines.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
struct ButtonComboInfo;
|
||||
|
||||
namespace ButtonComboUtils::API {
|
||||
namespace Internal {
|
||||
uint32_t CreateButtonComboData();
|
||||
void RemoveButtonComboData(uint32_t buttonComboManagerHandle);
|
||||
std::vector<ButtonComboInfo> GetButtonComboData(uint32_t buttonComboManagerHandle);
|
||||
} // namespace Internal
|
||||
|
||||
WUPSButtonCombo_Error AddButtonCombo(void *identifier,
|
||||
|
||||
@@ -236,6 +236,23 @@ CaptureStackTrace(uint32_t maxDepth) {
|
||||
|
||||
#define SC17_FindClosestSymbol ((uint32_t(*)(uint32_t addr, int32_t * outDistance, char *symbolNameBuffer, uint32_t symbolNameBufferLength, char *moduleNameBuffer, uint32_t moduleNameBufferLength))(0x101C400 + 0x1f934))
|
||||
|
||||
std::string getModuleAndSymbolName(uint32_t addr) {
|
||||
int distance = 0;
|
||||
char moduleName[50] = {};
|
||||
char symbolName[256] = {};
|
||||
|
||||
if (SC17_FindClosestSymbol(addr, &distance, symbolName, sizeof(symbolName) - 1, moduleName, sizeof(moduleName) - 1) != 0) {
|
||||
return string_format("0x%08X", addr);
|
||||
} else {
|
||||
moduleName[sizeof(moduleName) - 1] = '\0';
|
||||
symbolName[sizeof(symbolName) - 1] = '\0';
|
||||
return string_format("%s|%s+0x%X",
|
||||
moduleName,
|
||||
symbolName,
|
||||
distance);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintCapturedStackTrace(std::span<uint32_t> trace) {
|
||||
if (trace.empty()) {
|
||||
DEBUG_FUNCTION_LINE_INFO("┌────────────────────── CAPTURED TRACE ──────────────────────┐");
|
||||
@@ -248,8 +265,8 @@ void PrintCapturedStackTrace(std::span<uint32_t> trace) {
|
||||
for (size_t i = 0; i < trace.size(); ++i) {
|
||||
uint32_t addr = trace[i];
|
||||
int distance = 0;
|
||||
char moduleName[100] = {};
|
||||
char symbolName[100] = {};
|
||||
char moduleName[50] = {};
|
||||
char symbolName[256] = {};
|
||||
|
||||
if (SC17_FindClosestSymbol(addr, &distance, symbolName, sizeof(symbolName) - 1, moduleName, sizeof(moduleName) - 1) != 0) {
|
||||
DEBUG_FUNCTION_LINE_INFO("│ [%02d] 0x%08X", i, addr);
|
||||
|
||||
@@ -167,6 +167,8 @@ std::vector<std::string> getNonBaseAromaPluginFilenames(std::string_view basePat
|
||||
|
||||
std::vector<uint32_t> CaptureStackTrace(uint32_t maxDepth);
|
||||
|
||||
std::string getModuleAndSymbolName(uint32_t addr);
|
||||
|
||||
void PrintCapturedStackTrace(std::span<uint32_t> trace);
|
||||
|
||||
std::string hookNameToString(wups_loader_hook_type_t type);
|
||||
Reference in New Issue
Block a user