From 8735cf96adf5c876f953cb911793403afdeaa4d7 Mon Sep 17 00:00:00 2001 From: EmeraldLockdown <86802223+EmeraldLoc@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:49:01 -0500 Subject: [PATCH] Add `get_mod_files` (#1091) * Add `get_mod_files` * Dont allocate memory, use the stack * Implement peachy's suggestion * Actually allow optional to wrok --- autogen/lua_definitions/functions.lua | 8 +++++ docs/lua/functions-7.md | 24 ++++++++++++++ docs/lua/functions.md | 1 + src/pc/lua/smlua_functions_autogen.c | 23 +++++++++++++ src/pc/lua/utils/smlua_misc_utils.c | 48 +++++++++++++++++++++++++++ src/pc/lua/utils/smlua_misc_utils.h | 4 ++- 6 files changed, 107 insertions(+), 1 deletion(-) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 746a8f4c4..c716033b3 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -11647,6 +11647,14 @@ function get_active_mod() -- ... end +--- @param mod Mod +--- @param subDirectory? string +--- @return table +--- Gets all files a mod contains +function get_mod_files(mod, subDirectory) + -- ... +end + --- @param title string --- Sets the window title to a custom title function set_window_title(title) diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md index 207edbb6f..1dd27c2d7 100644 --- a/docs/lua/functions-7.md +++ b/docs/lua/functions-7.md @@ -2107,6 +2107,30 @@ Gets the mod currently being processed
+## [get_mod_files](#get_mod_files) + +### Description +Gets all files a mod contains + +### Lua Example +`local tableValue = get_mod_files(mod, subDirectory)` + +### Parameters +| Field | Type | +| ----- | ---- | +| mod | [Mod](structs.md#Mod) | +| subDirectory | `string` | + +### Returns +- `table` + +### C Prototype +`LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory);` + +[:arrow_up_small:](#) + +
+ ## [set_window_title](#set_window_title) ### Description diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 4076375df..ecce742d3 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -2071,6 +2071,7 @@ - [set_environment_region](functions-7.md#set_environment_region) - [mod_file_exists](functions-7.md#mod_file_exists) - [get_active_mod](functions-7.md#get_active_mod) + - [get_mod_files](functions-7.md#get_mod_files) - [set_window_title](functions-7.md#set_window_title) - [reset_window_title](functions-7.md#reset_window_title) - [get_os_name](functions-7.md#get_os_name) diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index e227a54aa..70d040309 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -34301,6 +34301,28 @@ int smlua_func_get_active_mod(UNUSED lua_State* L) { return 1; } +int smlua_func_get_mod_files(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top < 1 || top > 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "get_mod_files", 1, 2, top); + return 0; + } + + struct Mod* mod = (struct Mod*)smlua_to_cobject(L, 1, LOT_MOD); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_mod_files"); return 0; } + const char* subDirectory = (const char*) NULL; + if (top >= 2) { + subDirectory = smlua_to_string(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_mod_files"); return 0; } + } + + smlua_push_lua_table(L, get_mod_files(mod, subDirectory)); + + return 1; +} + int smlua_func_set_window_title(lua_State* L) { if (L == NULL) { return 0; } @@ -38685,6 +38707,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region); smlua_bind_function(L, "mod_file_exists", smlua_func_mod_file_exists); smlua_bind_function(L, "get_active_mod", smlua_func_get_active_mod); + smlua_bind_function(L, "get_mod_files", smlua_func_get_mod_files); smlua_bind_function(L, "set_window_title", smlua_func_set_window_title); smlua_bind_function(L, "reset_window_title", smlua_func_reset_window_title); smlua_bind_function(L, "get_os_name", smlua_func_get_os_name); diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index de447b3d1..9e90a45fb 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -607,6 +607,54 @@ struct Mod* get_active_mod(void) { return gLuaActiveMod; } +LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory) { + if (!mod) { + struct lua_State *L = gLuaState; + if (L) { + lua_newtable(L); + return smlua_to_lua_table(L, -1); + } + return 0; + } + + char normalizedSubDir[SYS_MAX_PATH] = { 0 }; + snprintf(normalizedSubDir, SYS_MAX_PATH, "%s", subDirectory ? subDirectory : ""); + normalize_path(normalizedSubDir); + + size_t subDirLen = strlen(normalizedSubDir); + if (subDirLen > 0 && subDirLen + 1 < SYS_MAX_PATH && normalizedSubDir[subDirLen - 1] != '/') { + strcat(normalizedSubDir, "/"); + subDirLen = strlen(normalizedSubDir); + } + + struct lua_State *L = gLuaState; + if (!L) { return 0; } + + LUA_STACK_CHECK_BEGIN_NUM(L, 1); + + lua_newtable(L); + + int luaTableIndex = 1; + for (int i = 0; i < mod->fileCount; i++) { + struct ModFile* file = &mod->files[i]; + char normalizedPath[SYS_MAX_PATH] = { 0 }; + if (snprintf(normalizedPath, SYS_MAX_PATH, "%s", file->relativePath) < 0) { + LOG_ERROR("Failed to copy relativePath for normalization: %s", file->relativePath); + continue; + } + normalize_path(normalizedPath); + + if (strncmp(normalizedPath, normalizedSubDir, subDirLen) == 0) { + lua_pushstring(L, file->relativePath); + lua_rawseti(L, -2, luaTableIndex++); + } + } + + LUA_STACK_CHECK_END(L); + + return smlua_to_lua_table(L, -1); +} + /// void set_window_title(const char* title) { diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index e4bb3c1eb..1b7d929cb 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -37,7 +37,7 @@ enum ActSelectHudPart { ACT_SELECT_HUD_ACT_NAME = 1 << 3, ACT_SELECT_HUD_STAR_NUM = 1 << 4, ACT_SELECT_HUD_PLAYERS_IN_LEVEL = 1 << 5, - + ACT_SELECT_HUD_NONE = 0, ACT_SELECT_HUD_ALL = ACT_SELECT_HUD_SCORE | ACT_SELECT_HUD_LEVEL_NAME | ACT_SELECT_HUD_COURSE_NUM | ACT_SELECT_HUD_ACT_NAME |ACT_SELECT_HUD_STAR_NUM | ACT_SELECT_HUD_PLAYERS_IN_LEVEL }; @@ -246,6 +246,8 @@ void set_environment_region(u8 index, s16 value); bool mod_file_exists(const char* filename); /* |description|Gets the mod currently being processed|descriptionEnd| */ struct Mod* get_active_mod(void); +/* |description|Gets all files a mod contains|descriptionEnd| */ +LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory); /* |description|Sets the window title to a custom title|descriptionEnd| */ void set_window_title(const char* title);