add a more accurate way to know the last active mod
Some checks are pending
Build coop / build-ubuntu (push) Waiting to run
Build coop / build-windows (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run

This commit is contained in:
Isaac0-dev 2025-04-22 09:47:26 +10:00
parent dcaa7e725d
commit bff72db960
6 changed files with 70 additions and 21 deletions

View file

@ -304,14 +304,15 @@ struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyInde
static struct LuaObjectField lof = { 0 };
if (lot != LOT_OBJECT) { return NULL; }
if (gLuaActiveMod == NULL) {
struct Mod *mod = smlua_get_last_active_mod(L);
if (mod == NULL) {
LOG_LUA_LINE("Failed to retrieve active mod entry.");
return NULL;
}
// get _custom_object_fields
lua_getglobal(L, "_G"); // get global table
lua_getfield(L, LUA_REGISTRYINDEX, gLuaActiveMod->relativePath); // push file's "global" table
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // push file's "global" table
int fileGlobalIndex = lua_gettop(L);
lua_getfield(L, fileGlobalIndex, "_custom_object_fields");
lua_remove(L, -2); // remove file's "global" table

View file

@ -739,27 +739,71 @@ void smlua_dump_table(int index) {
printf("--------------\n");
}
// Get the folder and file
// in the format: "folder/file.lua"
static const char *smlua_lua_path_to_relative(const char *src) {
int slashCount = 0;
for (const char* p = src + strlen(src); p > src; --p) {
if (*p == '/' || *p == '\\') {
if (++slashCount == 2) {
return p + 1;
}
}
}
return src;
}
// Get the folder from the path
static const char *smlua_lua_path_to_folder(const char *src) {
static char convertedBuffer[SYS_MAX_PATH];
memcpy(convertedBuffer, src, strlen(src)); // Assumes the sub string will be smaller
int slashCount = 0;
char *lastSlash = convertedBuffer;
for (char* p = convertedBuffer + strlen(convertedBuffer); p > convertedBuffer; --p) {
if (*p == '/' || *p == '\\') {
if (++slashCount == 2) {
*lastSlash = '\0'; // Insert a null terminator
return p + 1;
}
lastSlash = p;
}
}
return src;
}
// Get the last run mod via stack trace
// not the most efficient way, but its the most accurate
// try to call as little as possible, and use gLuaActiveMod
struct Mod *smlua_get_last_active_mod() {
lua_State* L = gLuaState;
lua_Debug info;
for (int level = 0; lua_getstack(L, level, &info); level++) {
if (!lua_getinfo(L, "S", &info)) { break; }
if (strcmp(info.what, "C") == 0) { continue; } // Skip C functions
// We found the first instance of Lua code
// compare the folder to all active mods
const char *modFolder = smlua_lua_path_to_folder(info.source);
for (u16 i = 0; i < gLocalMods.entryCount; i++) {
struct Mod *mod = gLocalMods.entries[i];
if (!mod->enabled) { continue; }
if (strcmp(mod->relativePath, modFolder) == 0) {
gLuaActiveMod = mod;
return mod;
}
}
break;
}
return NULL;
}
void smlua_logline(void) {
lua_State* L = gLuaState;
lua_Debug info;
int level = 0;
while (lua_getstack(L, level, &info)) {
lua_getinfo(L, "nSl", &info);
// Get the folder and file
// in the format: "folder/file.lua"
const char* src = info.source;
int slashCount = 0;
const char* folderStart = NULL;
for (const char* p = src + strlen(src); p > src; --p) {
if (*p == '/' || *p == '\\') {
if (++slashCount == 2) {
folderStart = p + 1;
break;
}
}
}
const char* folderStart = smlua_lua_path_to_relative(info.source);
LOG_LUA(" [%d] '%s':%d -- %s [%s]",
level, (folderStart ? folderStart : info.short_src), info.currentline,
(info.name ? info.name : "<unknown>"), info.what);

View file

@ -50,6 +50,7 @@ s64 smlua_get_any_integer_mod_variable(const char* variable);
LuaFunction smlua_get_function_mod_variable(u16 modIndex, const char *variable);
LuaFunction smlua_get_any_function_mod_variable(const char *variable);
struct Mod *smlua_get_last_active_mod();
void smlua_logline(void);
void smlua_dump_stack(void);
void smlua_dump_globals(void);

View file

@ -515,7 +515,7 @@ bool mod_file_exists(const char* filename) {
}
struct Mod* get_active_mod(void) {
return gLuaActiveMod;
return smlua_get_last_active_mod();
}
///

View file

@ -58,8 +58,10 @@ bool char_valid(const char* buffer, bool isKey) {
}
void mod_storage_get_filename(char* dest) {
struct Mod *mod = smlua_get_last_active_mod();
if (mod == NULL) { return; }
const char* path = fs_get_write_path(SAVE_DIRECTORY); // get user path
snprintf(dest, SYS_MAX_PATH - 1, "%s/%s", path, gLuaActiveMod->relativePath); // append sav folder
snprintf(dest, SYS_MAX_PATH - 1, "%s/%s", path, mod->relativePath); // append sav folder
strdelete(dest, ".lua"); // delete ".lua" from sav name
strcat(dest, SAVE_EXTENSION); // append SAVE_EXTENSION
normalize_path(dest); // fix any out of place slashes

View file

@ -17,11 +17,12 @@ void network_send_lua_custom(bool broadcast) {
}
// figure out mod index
if (gLuaActiveMod == NULL) {
struct Mod *activeMod = smlua_get_last_active_mod();
if (activeMod == NULL) {
LOG_LUA_LINE("Could not figure out the current active mod!");
return;
}
u16 modIndex = gLuaActiveMod->index;
u16 modIndex = activeMod->index;
// get local index
s32 toLocalIndex = 0;