Add logic to handle the "reent" bug

This commit is contained in:
Maschell
2026-04-17 23:45:49 +02:00
parent 66fd70e759
commit a22da69f2d
11 changed files with 247 additions and 34 deletions

View File

@@ -5,15 +5,22 @@
#include "utils/logger.h"
#include "utils/utils.h"
#include <set>
#include <string>
#include <vector>
namespace WUPSBackendSettings {
namespace {
std::set<std::string> sInactivePlugins;
}
std::set<std::string> sBrokenReentPlugins;
bool isDirty = false;
} // namespace
#define INACTIVE_PLUGINS_KEY "inactive_plugins"
#define INACTIVE_PLUGINS_KEY "inactive_plugins"
#define BROKEN_REENT_PLUGINS_KEY "possibly_broken_reent_plugins"
bool IsDirty() {
return isDirty;
}
bool LoadSettings() {
nlohmann::json j = nlohmann::json::object();
@@ -28,15 +35,29 @@ namespace WUPSBackendSettings {
if (j.contains(INACTIVE_PLUGINS_KEY) && j[INACTIVE_PLUGINS_KEY].is_array()) {
for (auto &cur : j[INACTIVE_PLUGINS_KEY]) {
if (cur.is_string()) {
sInactivePlugins.insert(cur);
sInactivePlugins.insert(cur.get<std::string>());
}
}
}
sBrokenReentPlugins.clear();
if (j.contains(BROKEN_REENT_PLUGINS_KEY) && j[BROKEN_REENT_PLUGINS_KEY].is_array()) {
for (auto &cur : j[BROKEN_REENT_PLUGINS_KEY]) {
if (cur.is_string()) {
sBrokenReentPlugins.insert(cur.get<std::string>());
}
}
}
isDirty = false;
return true;
}
bool SaveSettings() {
if (!isDirty) {
return true;
}
std::string folderPath = getModulePath() + "/configs/";
std::string filePath = folderPath + "wupsbackend.json";
if (!FSUtils::CreateSubfolder(folderPath)) {
@@ -49,8 +70,9 @@ namespace WUPSBackendSettings {
return false;
}
nlohmann::json j = nlohmann::json::object();
j[INACTIVE_PLUGINS_KEY] = sInactivePlugins;
nlohmann::json j = nlohmann::json::object();
j[INACTIVE_PLUGINS_KEY] = sInactivePlugins;
j[BROKEN_REENT_PLUGINS_KEY] = sBrokenReentPlugins;
std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore);
auto writeResult = file.write((const uint8_t *) jsonString.c_str(), jsonString.size());
@@ -61,19 +83,41 @@ namespace WUPSBackendSettings {
return false;
}
isDirty = false;
return true;
}
void ClearInactivePluginFilenames() {
sInactivePlugins.clear();
if (!sInactivePlugins.empty()) {
sInactivePlugins.clear();
isDirty = true;
}
}
void AddInactivePluginFilename(const std::string &filename) {
sInactivePlugins.insert(filename);
if (sInactivePlugins.insert(filename).second) {
isDirty = true;
}
}
void AddBrokenReentPluginFilename(const std::string &filename) {
if (sBrokenReentPlugins.insert(filename).second) {
isDirty = true;
}
}
void RemoveBrokenReentPluginFilename(const std::string &filename) {
if (sBrokenReentPlugins.erase(filename) > 0) {
isDirty = true;
}
}
const std::set<std::string> &GetInactivePluginFilenames() {
return sInactivePlugins;
}
const std::set<std::string> &GetBrokenReentPluginFilenames() {
return sBrokenReentPlugins;
}
} // namespace WUPSBackendSettings

View File

@@ -21,4 +21,8 @@ namespace WUPSBackendSettings {
}
const std::set<std::string> &GetInactivePluginFilenames();
const std::set<std::string> &GetBrokenReentPluginFilenames();
void AddBrokenReentPluginFilename(const std::string &filename);
void RemoveBrokenReentPluginFilename(const std::string &filename);
}; // namespace WUPSBackendSettings

View File

@@ -235,11 +235,9 @@ void ConfigUtils::displayMenu() {
std::vector<std::string> newInactivePluginsList;
for (const auto &cur : newActivePluginsList) {
if (!cur.isLoadAndLink()) {
auto &source = cur.getPluginData()->getSource();
if (source.starts_with(getPluginPath()) && source.ends_with(".wps")) {
std::size_t found = source.find_last_of("/\\");
std::string filename = source.substr(found + 1);
newInactivePluginsList.push_back(filename);
const auto &source = cur.getPluginData()->getSource();
if (const auto filenameOpt = getPluginFilename(source); filenameOpt) {
newInactivePluginsList.push_back(*filenameOpt);
}
}
}

View File

@@ -343,4 +343,48 @@ const char *hookNameToString(const wups_loader_hook_type_t type) {
return "WUPS_LOADER_HOOK_INIT_REENT_FUNCTIONS";
}
return "<UNKNOWN>";
}
std::optional<std::string> getPluginFilename(const std::string &source) {
if (source.starts_with(getPluginPath()) && source.ends_with(".wps")) {
const std::size_t found = source.find_last_of("/\\");
return source.substr(found + 1);
}
return std::nullopt;
}
time_t parseBuildDate(const char *s) {
// Expected format: "Apr 16 2026" (ignoring any trailing time)
if (!s || strlen(s) < 11) {
return 0;
}
static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
tm t = {};
// 1. Identify Month (0-2)
t.tm_mon = -1;
for (int i = 0; i < 12; ++i) {
if (strncmp(s, months[i], 3) == 0) {
t.tm_mon = i;
break;
}
}
if (t.tm_mon == -1) return 0;
// 2. Parse Day (starts at index 4)
t.tm_mday = static_cast<int>(strtol(s + 4, nullptr, 10));
// 3. Parse Year (starts at index 7)
// strtol will stop at the space before the time string automatically
t.tm_year = static_cast<int>(strtol(s + 7, nullptr, 10)) - 1900;
// We only care about the date, so we zero out the time
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = -1;
return mktime(&t);
}

View File

@@ -171,4 +171,12 @@ std::string getModuleAndSymbolName(uint32_t addr);
void PrintCapturedStackTrace(std::span<const uint32_t> trace);
const char *hookNameToString(wups_loader_hook_type_t type);
const char *hookNameToString(wups_loader_hook_type_t type);
/**
* Helper to extract the filename from the source path.
* Returns nullopt if the source isn't a standard plugin path.
*/
std::optional<std::string> getPluginFilename(const std::string &source);
time_t parseBuildDate(const char *s);