mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-12-17 13:32:33 +00:00
Add a safer version of Lua's require() (#847)
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
I didn't add standard Lua require() because I've always been afraid of it. I'm not sure we can guarantee which files it will read (or not read). Instead, here is a custom implementation. It should work more or less the same and allow for more modular code. For backwards compatibility reasons, all of the lua files in the base mod folder will be loaded as in the past. Aka one at a time and alphabetically. However, now coop will look for Lua files in subdirectories and will load them in when another Lua file calls require(). The file search order is more reasonable than normal Lua require(). It will first look for files relative to the currently running script. If there is no matching relative file, it will pick from any Lua file that is in any of the mod's subdirectories. --------- Co-authored-by: MysterD <myster@d>
This commit is contained in:
parent
8f1830b079
commit
24b92ecc2a
20 changed files with 473 additions and 149 deletions
|
|
@ -29,7 +29,7 @@ SMLUA_CALL_EVENT_HOOKS_SET_HOOK_RESULT = """
|
|||
|
||||
SMLUA_CALL_EVENT_HOOKS_CALLBACK = """
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, {n_inputs}, {n_outputs}, 0, hook->mod[i])) {{
|
||||
if (0 != smlua_call_hook(L, {n_inputs}, {n_outputs}, 0, hook->mod[i], hook->modFile[i])) {{
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[{hook_type}]);
|
||||
continue;
|
||||
}}{set_hook_result}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ void dynos_generate_packs(const char* directory);
|
|||
|
||||
// -- geos -- //
|
||||
void dynos_actor_override(struct Object* obj, void** aSharedChild);
|
||||
void dynos_add_actor_custom(s32 modIndex, const char *filePath, const char* geoName);
|
||||
void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName);
|
||||
const void* dynos_geolayout_get(const char *name);
|
||||
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, const char **token);
|
||||
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, s32 *modFileIndex, const char **token);
|
||||
void dynos_actor_register_modified_graph_node(struct GraphNode *node);
|
||||
|
||||
// -- collisions -- //
|
||||
|
|
@ -72,7 +72,7 @@ Collision *dynos_level_get_collision(u32 level, u16 area);
|
|||
|
||||
// -- behaviors -- //
|
||||
void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behaviorName);
|
||||
s32 dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript);
|
||||
bool dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex);
|
||||
const char *dynos_behavior_get_token(BehaviorScript *bhvScript, u32 index);
|
||||
void dynos_behavior_hook_all_custom_behaviors(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ struct GfxData : NoCopy {
|
|||
s32 mErrorCount = 0;
|
||||
u32 mModelIdentifier = 0;
|
||||
s32 mModIndex = 0;
|
||||
s32 mModFileIndex = 0;
|
||||
SysPath mPackFolder;
|
||||
Array<void *> mPointerList;
|
||||
Array<Pair<const void*, const void*>> mPointerOffsetList;
|
||||
|
|
@ -889,9 +890,9 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode<TexData>* aTexData);
|
|||
//
|
||||
|
||||
std::map<const void *, ActorGfx> &DynOS_Actor_GetValidActors();
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName);
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName);
|
||||
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
|
||||
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, const char **outToken);
|
||||
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, s32 *outModFileIndex, const char **outToken);
|
||||
ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode);
|
||||
void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx);
|
||||
void DynOS_Actor_Invalid(const void* aGeoref, s32 aPackIndex);
|
||||
|
|
@ -946,7 +947,7 @@ void DynOS_Lvl_ModShutdown();
|
|||
Array<Pair<const char *, GfxData *>> &DynOS_Bhv_GetArray();
|
||||
void DynOS_Bhv_Activate(s32 modIndex, const SysPath &aFilename, const char *aBehaviorName);
|
||||
GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript);
|
||||
s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript);
|
||||
bool DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex);
|
||||
const char *DynOS_Bhv_GetToken(BehaviorScript *bhvScript, u32 index);
|
||||
void DynOS_Bhv_HookAllCustomBehaviors();
|
||||
void DynOS_Bhv_ModShutdown();
|
||||
|
|
|
|||
|
|
@ -111,16 +111,16 @@ void dynos_actor_override(struct Object* obj, void** aSharedChild) {
|
|||
DynOS_Actor_Override(obj, aSharedChild);
|
||||
}
|
||||
|
||||
void dynos_add_actor_custom(s32 modIndex, const char *filePath, const char* geoName) {
|
||||
DynOS_Actor_AddCustom(modIndex, filePath, geoName);
|
||||
void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName) {
|
||||
DynOS_Actor_AddCustom(modIndex, modFileIndex, filePath, geoName);
|
||||
}
|
||||
|
||||
const void* dynos_geolayout_get(const char *name) {
|
||||
return DynOS_Actor_GetLayoutFromName(name);
|
||||
}
|
||||
|
||||
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, const char **token) {
|
||||
return DynOS_Actor_GetModIndexAndToken(graphNode, tokenIndex, modIndex, token);
|
||||
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, s32 *modFileIndex, const char **token) {
|
||||
return DynOS_Actor_GetModIndexAndToken(graphNode, tokenIndex, modIndex, modFileIndex, token);
|
||||
}
|
||||
|
||||
void dynos_actor_register_modified_graph_node(struct GraphNode *node) {
|
||||
|
|
@ -232,8 +232,8 @@ void dynos_add_behavior(s32 modIndex, const char *filePath, const char *behavior
|
|||
DynOS_Bhv_Activate(modIndex, filePath, behaviorName);
|
||||
}
|
||||
|
||||
s32 dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript) {
|
||||
return DynOS_Bhv_GetActiveModIndex(bhvScript);
|
||||
bool dynos_behavior_get_active_mod_index(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex) {
|
||||
return DynOS_Bhv_GetActiveModIndex(bhvScript, modIndex, modFileIndex);
|
||||
}
|
||||
|
||||
const char *dynos_behavior_get_token(BehaviorScript *bhvScript, u32 index) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ std::map<const void *, ActorGfx> &DynOS_Actor_GetValidActors() {
|
|||
return DynosValidActors();
|
||||
}
|
||||
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName) {
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName) {
|
||||
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
||||
|
||||
u16 actorLen = strlen(aActorName);
|
||||
|
|
@ -45,6 +45,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *
|
|||
return;
|
||||
}
|
||||
_GfxData->mModIndex = aModIndex;
|
||||
_GfxData->mModFileIndex = aModFileIndex;
|
||||
|
||||
void* geoLayout = (*(_GfxData->mGeoLayouts.end() - 1))->mData;
|
||||
if (!geoLayout) {
|
||||
|
|
@ -117,7 +118,7 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, const char **outToken) {
|
||||
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, s32 *outModFileIndex, const char **outToken) {
|
||||
ActorGfx *_ActorGfx = DynOS_Actor_GetActorGfx(aGraphNode);
|
||||
if (_ActorGfx) {
|
||||
GfxData *_GfxData = _ActorGfx->mGfxData;
|
||||
|
|
@ -125,6 +126,9 @@ bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenInde
|
|||
if (outModIndex) {
|
||||
*outModIndex = _GfxData->mModIndex;
|
||||
}
|
||||
if (outModFileIndex) {
|
||||
*outModFileIndex = _GfxData->mModFileIndex;
|
||||
}
|
||||
if (outToken) {
|
||||
if (!aTokenIndex || aTokenIndex > _GfxData->mLuaTokenList.Count()) {
|
||||
return false;
|
||||
|
|
@ -139,6 +143,9 @@ bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenInde
|
|||
if (outModIndex) {
|
||||
*outModIndex = _GfxData->mModIndex;
|
||||
}
|
||||
if (outModFileIndex) {
|
||||
*outModFileIndex = _GfxData->mModFileIndex;
|
||||
}
|
||||
if (outToken) {
|
||||
if (!aTokenIndex || aTokenIndex > _GfxData->mLuaTokenList.Count()) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript) {
|
||||
bool DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex) {
|
||||
auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray();
|
||||
|
||||
for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) {
|
||||
|
|
@ -70,10 +70,12 @@ s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript) {
|
|||
auto &scripts = gfxData->mBehaviorScripts;
|
||||
if (scripts.Count() == 0) { continue; }
|
||||
if (bhvScript == scripts[scripts.Count() - 1]->mData) {
|
||||
return gfxData->mModIndex;
|
||||
*modIndex = gfxData->mModIndex;
|
||||
*modFileIndex = gfxData->mModFileIndex;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *DynOS_Bhv_GetToken(BehaviorScript *bhvScript, u32 index) {
|
||||
|
|
|
|||
|
|
@ -913,8 +913,9 @@ static s32 bhv_cmd_call_ext(void) {
|
|||
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
|
|
@ -946,8 +947,9 @@ static s32 bhv_cmd_call_ext(void) {
|
|||
static s32 bhv_cmd_goto_ext(void) {
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
|
|
@ -976,8 +978,9 @@ static s32 bhv_cmd_goto_ext(void) {
|
|||
static s32 bhv_cmd_call_native_ext(void) {
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
|
|
@ -994,19 +997,27 @@ static s32 bhv_cmd_call_native_ext(void) {
|
|||
}
|
||||
|
||||
if (!gSmLuaConvertSuccess || funcRef == 0) {
|
||||
LOG_LUA("Failed to call lua function, could not find lua function '%s'", funcStr);
|
||||
LOG_LUA("Failed to call lua behavior function, could not find lua function '%s'", funcStr);
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
|
||||
// Get our mod.
|
||||
if (modIndex >= gActiveMods.entryCount) {
|
||||
LOG_LUA("Failed to call lua function, could not find mod");
|
||||
if (modIndex < 0 || modIndex >= gActiveMods.entryCount) {
|
||||
LOG_LUA("Failed to call lua behavior function, could not find mod");
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
struct Mod *mod = gActiveMods.entries[modIndex];
|
||||
|
||||
// Get our mod file
|
||||
if (modFileIndex < 0 || modFileIndex >= mod->fileCount) {
|
||||
LOG_LUA("Failed to call lua behavior function, could not find mod file %d", modFileIndex);
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
struct ModFile *modFile = &mod->files[modFileIndex];
|
||||
|
||||
// Push the callback onto the stack
|
||||
lua_rawgeti(gLuaState, LUA_REGISTRYINDEX, funcRef);
|
||||
|
||||
|
|
@ -1014,7 +1025,7 @@ static s32 bhv_cmd_call_native_ext(void) {
|
|||
smlua_push_object(gLuaState, LOT_OBJECT, gCurrentObject, NULL);
|
||||
|
||||
// Call the callback
|
||||
if (0 != smlua_call_hook(gLuaState, 1, 0, 0, mod)) {
|
||||
if (0 != smlua_call_hook(gLuaState, 1, 0, 0, mod, modFile)) {
|
||||
LOG_LUA("Failed to call the function callback: '%s'", funcStr);
|
||||
}
|
||||
|
||||
|
|
@ -1029,8 +1040,9 @@ static s32 bhv_cmd_spawn_child_ext(void) {
|
|||
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
gCurBhvCommand += 3;
|
||||
return BHV_PROC_CONTINUE;
|
||||
|
|
@ -1076,8 +1088,9 @@ static s32 bhv_cmd_spawn_child_with_param_ext(void) {
|
|||
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
gCurBhvCommand += 3;
|
||||
return BHV_PROC_CONTINUE;
|
||||
|
|
@ -1123,8 +1136,9 @@ static s32 bhv_cmd_spawn_obj_ext(void) {
|
|||
|
||||
BehaviorScript *behavior = (BehaviorScript *)gCurrentObject->behavior;
|
||||
|
||||
s32 modIndex = dynos_behavior_get_active_mod_index(behavior);
|
||||
if (modIndex == -1) {
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
if (!dynos_behavior_get_active_mod_index(behavior, &modIndex, &modFileIndex)) {
|
||||
LOG_ERROR("Could not find behavior script mod index.");
|
||||
gCurBhvCommand += 3;
|
||||
return BHV_PROC_CONTINUE;
|
||||
|
|
|
|||
|
|
@ -877,8 +877,9 @@ Gfx *geo_process_lua_function(s32 callContext, struct GraphNode *node, UNUSED Ma
|
|||
|
||||
// Retrieve mod index and function name
|
||||
s32 modIndex = -1;
|
||||
s32 modFileIndex = -1;
|
||||
const char *funcStr = NULL;
|
||||
if (!dynos_actor_get_mod_index_and_token(sharedChild, fnNode->luaTokenIndex, &modIndex, &funcStr)) {
|
||||
if (!dynos_actor_get_mod_index_and_token(sharedChild, fnNode->luaTokenIndex, &modIndex, &modFileIndex, &funcStr)) {
|
||||
if (modIndex == -1) {
|
||||
LOG_ERROR("Could not find graph node mod index");
|
||||
} else if (funcStr == NULL) {
|
||||
|
|
@ -895,24 +896,32 @@ Gfx *geo_process_lua_function(s32 callContext, struct GraphNode *node, UNUSED Ma
|
|||
funcRef = smlua_get_any_function_mod_variable(funcStr);
|
||||
}
|
||||
if (!gSmLuaConvertSuccess || funcRef == 0) {
|
||||
LOG_LUA("Failed to call lua function, could not find lua function '%s'", funcStr);
|
||||
LOG_LUA("Failed to call lua geo function, could not find lua function '%s'", funcStr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the mod
|
||||
if (modIndex >= gActiveMods.entryCount) {
|
||||
LOG_LUA("Failed to call lua function, could not find mod");
|
||||
if (modIndex < 0 || modIndex >= gActiveMods.entryCount) {
|
||||
LOG_LUA("Failed to call lua geo function, could not find mod");
|
||||
return NULL;
|
||||
}
|
||||
struct Mod *mod = gActiveMods.entries[modIndex];
|
||||
|
||||
// Get our mod file
|
||||
if (modFileIndex < 0 || modFileIndex >= mod->fileCount) {
|
||||
LOG_LUA("Failed to call lua geo function, could not find mod file %d", modFileIndex);
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
}
|
||||
struct ModFile *modFile = &mod->files[modFileIndex];
|
||||
|
||||
// Push the callback, the graph node and the current matrix stack index
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, funcRef);
|
||||
smlua_push_object(L, LOT_GRAPHNODE, node, NULL);
|
||||
lua_pushinteger(L, gMatStackIndex);
|
||||
|
||||
// Call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, mod)) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, mod, modFile)) {
|
||||
LOG_LUA("Failed to call the function callback: '%s'", funcStr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "smlua.h"
|
||||
#include "pc/lua/smlua_require.h"
|
||||
#include "game/hardcoded.h"
|
||||
#include "pc/mods/mods.h"
|
||||
#include "pc/mods/mods_utils.h"
|
||||
|
|
@ -16,6 +17,7 @@ u8 gLuaInitializingScript = 0;
|
|||
u8 gSmLuaSuppressErrors = 0;
|
||||
struct Mod* gLuaLoadingMod = NULL;
|
||||
struct Mod* gLuaActiveMod = NULL;
|
||||
struct ModFile* gLuaActiveModFile = NULL;
|
||||
struct Mod* gLuaLastHookMod = NULL;
|
||||
|
||||
void smlua_mod_error(void) {
|
||||
|
|
@ -190,12 +192,11 @@ static bool smlua_check_binary_header(struct ModFile *file) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteIndex) {
|
||||
void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteIndex, bool isModInit) {
|
||||
if (!smlua_check_binary_header(file)) return;
|
||||
|
||||
lua_State* L = gLuaState;
|
||||
|
||||
lua_settop(L, 0);
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
gSmLuaConvertSuccess = true;
|
||||
gLuaInitializingScript = 1;
|
||||
|
|
@ -205,6 +206,7 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
if (!f) {
|
||||
LOG_LUA("Failed to load lua script '%s': File not found.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
lua_settop(L, prevTop);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -214,6 +216,7 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
if (!buffer) {
|
||||
LOG_LUA("Failed to load lua script '%s': Cannot allocate buffer.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
lua_settop(L, prevTop);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +224,7 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
if (f_read(buffer, 1, length, f) < length) {
|
||||
LOG_LUA("Failed to load lua script '%s': Unexpected early end of file.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
lua_settop(L, prevTop);
|
||||
return;
|
||||
}
|
||||
f_close(f);
|
||||
|
|
@ -231,51 +235,66 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
LOG_LUA("%s", smlua_to_string(L, lua_gettop(L)));
|
||||
gLuaInitializingScript = 0;
|
||||
free(buffer);
|
||||
lua_settop(L, prevTop);
|
||||
return;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
// check if this is the first time this mod has been loaded
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
bool firstInit = (lua_type(L, -1) == LUA_TNIL);
|
||||
lua_pop(L, 1);
|
||||
if (isModInit) {
|
||||
// check if this is the first time this mod has been loaded
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
bool firstInit = (lua_type(L, -1) == LUA_TNIL);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// create mod's "global" table
|
||||
if (firstInit) {
|
||||
lua_newtable(L); // create _ENV tables
|
||||
lua_newtable(L); // create metatable
|
||||
lua_getglobal(L, "_G"); // get global table
|
||||
// create mod's "global" table
|
||||
if (firstInit) {
|
||||
lua_newtable(L); // create _ENV tables
|
||||
lua_newtable(L); // create metatable
|
||||
lua_getglobal(L, "_G"); // get global table
|
||||
|
||||
// remove certain default functions
|
||||
lua_pushstring(L, "load"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "loadfile"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "loadstring"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "collectgarbage"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "dofile"); lua_pushnil(L); lua_settable(L, -3);
|
||||
// remove certain default functions
|
||||
lua_pushstring(L, "load"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "loadfile"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "loadstring"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "collectgarbage"); lua_pushnil(L); lua_settable(L, -3);
|
||||
lua_pushstring(L, "dofile"); lua_pushnil(L); lua_settable(L, -3);
|
||||
|
||||
// set global as the metatable
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
// set global as the metatable
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// push to registry with path as name (must be unique)
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
}
|
||||
// push to registry with path as name (must be unique)
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
}
|
||||
|
||||
// load mod's "global" table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
lua_setupvalue(L, 1, 1); // set upvalue (_ENV)
|
||||
// load mod's "global" table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
lua_setupvalue(L, 1, 1); // set upvalue (_ENV)
|
||||
|
||||
// load per-file globals
|
||||
if (firstInit) {
|
||||
smlua_sync_table_init_globals(mod->relativePath, remoteIndex);
|
||||
smlua_cobject_init_per_file_globals(mod->relativePath);
|
||||
// load per-file globals
|
||||
if (firstInit) {
|
||||
smlua_sync_table_init_globals(mod->relativePath, remoteIndex);
|
||||
smlua_cobject_init_per_file_globals(mod->relativePath);
|
||||
}
|
||||
} else {
|
||||
// this block is run on files that are loaded for 'require' function
|
||||
// get the mod's global table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
LOG_LUA("mod environment not found");
|
||||
lua_settop(L, prevTop);
|
||||
return;
|
||||
}
|
||||
lua_setupvalue(L, -2, 1); // set _ENV
|
||||
}
|
||||
|
||||
// run chunks
|
||||
LOG_INFO("Executing '%s'", file->relativePath);
|
||||
if (smlua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK) {
|
||||
if (smlua_pcall(L, 0, 1, 0) != LUA_OK) {
|
||||
LOG_LUA("Failed to execute lua script '%s'.", file->cachedPath);
|
||||
}
|
||||
|
||||
gLuaInitializingScript = 0;
|
||||
}
|
||||
|
||||
|
|
@ -304,6 +323,7 @@ void smlua_init(void) {
|
|||
smlua_bind_functions();
|
||||
smlua_bind_functions_autogen();
|
||||
smlua_bind_sync_table();
|
||||
smlua_init_require_system();
|
||||
|
||||
extern char gSmluaConstants[];
|
||||
smlua_exec_str(gSmluaConstants);
|
||||
|
|
@ -324,12 +344,22 @@ void smlua_init(void) {
|
|||
gPcDebug.lastModRun = gLuaActiveMod;
|
||||
for (int j = 0; j < mod->fileCount; j++) {
|
||||
struct ModFile* file = &mod->files[j];
|
||||
// skip loading non-lua files
|
||||
if (!(str_ends_with(file->relativePath, ".lua") || str_ends_with(file->relativePath, ".luac"))) {
|
||||
continue;
|
||||
}
|
||||
smlua_load_script(mod, file, i);
|
||||
|
||||
// skip loading scripts in subdirectories
|
||||
if (strchr(file->relativePath, '/') != NULL || strchr(file->relativePath, '\\') != NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gLuaActiveModFile = file;
|
||||
smlua_load_script(mod, file, i, true);
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
gLuaActiveMod = NULL;
|
||||
gLuaActiveModFile = NULL;
|
||||
gLuaLoadingMod = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -374,5 +404,6 @@ void smlua_shutdown(void) {
|
|||
}
|
||||
gLuaLoadingMod = NULL;
|
||||
gLuaActiveMod = NULL;
|
||||
gLuaActiveModFile = NULL;
|
||||
gLuaLastHookMod = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ extern u8 gLuaInitializingScript;
|
|||
extern u8 gSmLuaSuppressErrors;
|
||||
extern struct Mod* gLuaLoadingMod;
|
||||
extern struct Mod* gLuaActiveMod;
|
||||
extern struct ModFile* gLuaActiveModFile;
|
||||
extern struct Mod* gLuaLastHookMod;
|
||||
|
||||
void smlua_mod_error(void);
|
||||
|
|
@ -46,6 +47,7 @@ int smlua_error_handler(UNUSED lua_State* L);
|
|||
int smlua_pcall(lua_State* L, int nargs, int nresults, int errfunc);
|
||||
void smlua_exec_file(const char* path);
|
||||
void smlua_exec_str(const char* str);
|
||||
void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteIndex, bool isModInit);
|
||||
|
||||
void smlua_init(void);
|
||||
void smlua_update(void);
|
||||
|
|
|
|||
|
|
@ -475,6 +475,7 @@ int smlua_func_texture_override_reset(lua_State* L) {
|
|||
struct LuaLevelScriptParse {
|
||||
int reference;
|
||||
struct Mod* mod;
|
||||
struct ModFile* modFile;
|
||||
};
|
||||
|
||||
struct LuaLevelScriptParse sLevelScriptParse = { 0 };
|
||||
|
|
@ -635,7 +636,7 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
|
|||
}
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, preprocess->mod)) {
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, preprocess->mod, preprocess->modFile)) {
|
||||
LOG_LUA("Failed to call the callback behaviors: %u", type);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -664,6 +665,7 @@ void smlua_func_level_script_parse(lua_State* L) {
|
|||
|
||||
preprocess->reference = ref;
|
||||
preprocess->mod = gLuaActiveMod;
|
||||
preprocess->modFile = gLuaActiveModFile;
|
||||
|
||||
void *script = dynos_level_get_script(levelNum);
|
||||
if (script == NULL) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ bool smlua_call_event_hooks_HOOK_UPDATE() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_UPDATE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ bool smlua_call_event_hooks_HOOK_MARIO_UPDATE(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_MARIO_UPDATE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ bool smlua_call_event_hooks_HOOK_BEFORE_MARIO_UPDATE(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_BEFORE_MARIO_UPDATE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ bool smlua_call_event_hooks_HOOK_ON_SET_MARIO_ACTION(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SET_MARIO_ACTION]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ bool smlua_call_event_hooks_HOOK_BEFORE_PHYS_STEP(struct MarioState *m, s32 step
|
|||
lua_pushinteger(L, stepArg);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_BEFORE_PHYS_STEP]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ bool smlua_call_event_hooks_HOOK_ALLOW_PVP_ATTACK(struct MarioState *attacker, s
|
|||
lua_pushinteger(L, interaction);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ALLOW_PVP_ATTACK]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -229,7 +229,7 @@ bool smlua_call_event_hooks_HOOK_ON_PVP_ATTACK(struct MarioState *attacker, stru
|
|||
lua_pushinteger(L, interaction);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PVP_ATTACK]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ bool smlua_call_event_hooks_HOOK_ON_PLAYER_CONNECTED(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PLAYER_CONNECTED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -289,7 +289,7 @@ bool smlua_call_event_hooks_HOOK_ON_PLAYER_DISCONNECTED(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PLAYER_DISCONNECTED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ bool smlua_call_event_hooks_HOOK_ALLOW_INTERACT(struct MarioState *m, struct Obj
|
|||
lua_pushinteger(L, interactType);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ALLOW_INTERACT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ bool smlua_call_event_hooks_HOOK_ON_INTERACT(struct MarioState *m, struct Object
|
|||
lua_pushboolean(L, interactValue);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 4, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 4, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_INTERACT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -408,7 +408,7 @@ bool smlua_call_event_hooks_HOOK_ON_LEVEL_INIT(u8 warpType, s16 levelNum, u8 are
|
|||
lua_pushinteger(L, warpArg);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_LEVEL_INIT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -447,7 +447,7 @@ bool smlua_call_event_hooks_HOOK_ON_WARP(u8 warpType, s16 levelNum, u8 areaIdx,
|
|||
lua_pushinteger(L, warpArg);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 5, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_WARP]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -471,7 +471,7 @@ bool smlua_call_event_hooks_HOOK_ON_SYNC_VALID() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SYNC_VALID]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -498,7 +498,7 @@ bool smlua_call_event_hooks_HOOK_ON_OBJECT_UNLOAD(struct Object *obj) {
|
|||
smlua_push_object(L, LOT_OBJECT, obj, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_OBJECT_UNLOAD]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -525,7 +525,7 @@ bool smlua_call_event_hooks_HOOK_ON_SYNC_OBJECT_UNLOAD(struct Object *obj) {
|
|||
smlua_push_object(L, LOT_OBJECT, obj, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SYNC_OBJECT_UNLOAD]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -552,7 +552,7 @@ bool smlua_call_event_hooks_HOOK_ON_PAUSE_EXIT(bool usedExitToCastle, bool *allo
|
|||
lua_pushboolean(L, usedExitToCastle);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PAUSE_EXIT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -580,7 +580,7 @@ bool smlua_call_event_hooks_HOOK_GET_STAR_COLLECTION_DIALOG(s32 *dialogID) {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_GET_STAR_COLLECTION_DIALOG]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -618,7 +618,7 @@ bool smlua_call_event_hooks_HOOK_ON_SET_CAMERA_MODE(struct Camera *c, s16 mode,
|
|||
lua_pushinteger(L, frames);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SET_CAMERA_MODE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -650,7 +650,7 @@ bool smlua_call_event_hooks_HOOK_ON_OBJECT_RENDER(struct Object *obj) {
|
|||
smlua_push_object(L, LOT_OBJECT, obj, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_OBJECT_RENDER]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -680,7 +680,7 @@ bool smlua_call_event_hooks_HOOK_ON_DEATH(struct MarioState *m, bool *allowDeath
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_DEATH]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -715,7 +715,7 @@ bool smlua_call_event_hooks_HOOK_ON_PACKET_RECEIVE(s32 modIndex, s32 valueIndex)
|
|||
lua_pushinteger(L, valueIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PACKET_RECEIVE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -741,7 +741,7 @@ bool smlua_call_event_hooks_HOOK_USE_ACT_SELECT(s32 levelNum, bool *useActSelect
|
|||
lua_pushinteger(L, levelNum);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_USE_ACT_SELECT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -774,7 +774,7 @@ bool smlua_call_event_hooks_HOOK_ON_CHANGE_CAMERA_ANGLE(s32 camAngleType, bool *
|
|||
lua_pushinteger(L, camAngleType);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_CHANGE_CAMERA_ANGLE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -806,7 +806,7 @@ bool smlua_call_event_hooks_HOOK_ON_SCREEN_TRANSITION(s32 transitionType, bool *
|
|||
lua_pushinteger(L, transitionType);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SCREEN_TRANSITION]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -844,7 +844,7 @@ bool smlua_call_event_hooks_HOOK_ALLOW_HAZARD_SURFACE(struct MarioState *m, s32
|
|||
lua_pushinteger(L, hazardType);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ALLOW_HAZARD_SURFACE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -882,7 +882,7 @@ bool smlua_call_event_hooks_HOOK_ON_CHAT_MESSAGE(struct MarioState *m, const cha
|
|||
lua_pushstring(L, message);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_CHAT_MESSAGE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -920,7 +920,7 @@ bool smlua_call_event_hooks_HOOK_OBJECT_SET_MODEL(struct Object *obj, s32 modelI
|
|||
lua_pushinteger(L, modelExtendedId);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_OBJECT_SET_MODEL]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -952,7 +952,7 @@ bool smlua_call_event_hooks_HOOK_CHARACTER_SOUND(struct MarioState *m, enum Char
|
|||
lua_pushinteger(L, characterSound);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_CHARACTER_SOUND]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -994,7 +994,7 @@ bool smlua_call_event_hooks_HOOK_BEFORE_SET_MARIO_ACTION(struct MarioState *m, u
|
|||
lua_pushinteger(L, actionArg);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_BEFORE_SET_MARIO_ACTION]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1023,7 +1023,7 @@ bool smlua_call_event_hooks_HOOK_JOINED_GAME() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_JOINED_GAME]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1050,7 +1050,7 @@ bool smlua_call_event_hooks_HOOK_ON_OBJECT_ANIM_UPDATE(struct Object *obj) {
|
|||
smlua_push_object(L, LOT_OBJECT, obj, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_OBJECT_ANIM_UPDATE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1077,7 +1077,7 @@ bool smlua_call_event_hooks_HOOK_ON_DIALOG(s32 dialogID, bool *openDialogBox, co
|
|||
lua_pushinteger(L, dialogID);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 2, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 2, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_DIALOG]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1111,7 +1111,7 @@ bool smlua_call_event_hooks_HOOK_ON_EXIT() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_EXIT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1137,7 +1137,7 @@ bool smlua_call_event_hooks_HOOK_DIALOG_SOUND(s32 speaker, s32 *speakerOverride)
|
|||
lua_pushinteger(L, speaker);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_DIALOG_SOUND]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1173,7 +1173,7 @@ bool smlua_call_event_hooks_HOOK_ON_COLLIDE_LEVEL_BOUNDS(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_COLLIDE_LEVEL_BOUNDS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1203,7 +1203,7 @@ bool smlua_call_event_hooks_HOOK_MIRROR_MARIO_RENDER(struct GraphNodeObject *mir
|
|||
lua_pushinteger(L, playerIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_MIRROR_MARIO_RENDER]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1232,7 +1232,7 @@ bool smlua_call_event_hooks_HOOK_MARIO_OVERRIDE_PHYS_STEP_DEFACTO_SPEED(struct M
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_MARIO_OVERRIDE_PHYS_STEP_DEFACTO_SPEED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1264,7 +1264,7 @@ bool smlua_call_event_hooks_HOOK_ON_OBJECT_LOAD(struct Object *obj) {
|
|||
smlua_push_object(L, LOT_OBJECT, obj, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_OBJECT_LOAD]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1294,7 +1294,7 @@ bool smlua_call_event_hooks_HOOK_ON_PLAY_SOUND(s32 soundBits, Vec3f pos, s32 *so
|
|||
smlua_new_vec3f(pos);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_PLAY_SOUND]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1332,7 +1332,7 @@ bool smlua_call_event_hooks_HOOK_ON_SEQ_LOAD(u32 seqPlayer, u32 seqId, s32 loadA
|
|||
lua_pushinteger(L, loadAsync);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_SEQ_LOAD]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1374,7 +1374,7 @@ bool smlua_call_event_hooks_HOOK_ON_ATTACK_OBJECT(struct MarioState *m, struct O
|
|||
lua_pushinteger(L, interaction);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_ATTACK_OBJECT]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1401,7 +1401,7 @@ bool smlua_call_event_hooks_HOOK_ON_LANGUAGE_CHANGED(const char *langName) {
|
|||
lua_pushstring(L, langName);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_LANGUAGE_CHANGED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1425,7 +1425,7 @@ bool smlua_call_event_hooks_HOOK_ON_MODS_LOADED() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_MODS_LOADED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1449,7 +1449,7 @@ bool smlua_call_event_hooks_HOOK_ON_DJUI_THEME_CHANGED() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_DJUI_THEME_CHANGED]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1479,7 +1479,7 @@ bool smlua_call_event_hooks_HOOK_ON_GEO_PROCESS(struct GraphNode *node, s32 matS
|
|||
lua_pushinteger(L, matStackIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_GEO_PROCESS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1509,7 +1509,7 @@ bool smlua_call_event_hooks_HOOK_BEFORE_GEO_PROCESS(struct GraphNode *node, s32
|
|||
lua_pushinteger(L, matStackIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_BEFORE_GEO_PROCESS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1539,7 +1539,7 @@ bool smlua_call_event_hooks_HOOK_ON_GEO_PROCESS_CHILDREN(struct GraphNode *paren
|
|||
lua_pushinteger(L, matStackIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_GEO_PROCESS_CHILDREN]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1569,7 +1569,7 @@ bool smlua_call_event_hooks_HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS(struct MarioStat
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1604,7 +1604,7 @@ bool smlua_call_event_hooks_HOOK_ON_INTERACTIONS(struct MarioState *m) {
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_INTERACTIONS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1637,7 +1637,7 @@ bool smlua_call_event_hooks_HOOK_ALLOW_FORCE_WATER_ACTION(struct MarioState *m,
|
|||
lua_pushboolean(L, isInWaterAction);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ALLOW_FORCE_WATER_ACTION]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1677,7 +1677,7 @@ bool smlua_call_event_hooks_HOOK_BEFORE_WARP(s16 destLevel, s16 destArea, s16 de
|
|||
lua_pushinteger(L, arg);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 4, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 4, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_BEFORE_WARP]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1735,7 +1735,7 @@ bool smlua_call_event_hooks_HOOK_ON_INSTANT_WARP(u8 areaIdx, u8 nodeId, Vec3s di
|
|||
smlua_new_vec3s(displacement);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 3, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_INSTANT_WARP]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1767,7 +1767,7 @@ bool smlua_call_event_hooks_HOOK_MARIO_OVERRIDE_FLOOR_CLASS(struct MarioState *m
|
|||
lua_pushinteger(L, floorClass);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_MARIO_OVERRIDE_FLOOR_CLASS]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1803,7 +1803,7 @@ bool smlua_call_event_hooks_HOOK_ON_ADD_SURFACE(struct Surface *surface, bool dy
|
|||
lua_pushboolean(L, dynamic);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_ADD_SURFACE]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1827,7 +1827,7 @@ bool smlua_call_event_hooks_HOOK_ON_CLEAR_AREAS() {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_CLEAR_AREAS]);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ u64* gBehaviorOffset = &gPcDebug.bhvOffset;
|
|||
struct LuaHookedEvent {
|
||||
int reference[MAX_HOOKED_REFERENCES];
|
||||
struct Mod* mod[MAX_HOOKED_REFERENCES];
|
||||
struct ModFile* modFile[MAX_HOOKED_REFERENCES];
|
||||
int count;
|
||||
};
|
||||
|
||||
|
|
@ -46,11 +47,14 @@ static const char* sLuaHookedEventTypeName[] = {
|
|||
"HOOK_MAX"
|
||||
};
|
||||
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod) {
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile) {
|
||||
if (!gGameInited) { return 0; } // Don't call hooks while the game is booting
|
||||
|
||||
struct Mod* prev = gLuaActiveMod;
|
||||
struct Mod* prevActiveMod = gLuaActiveMod;
|
||||
struct ModFile* prevActiveModFile = gLuaActiveModFile;
|
||||
|
||||
gLuaActiveMod = activeMod;
|
||||
gLuaActiveModFile = activeModFile;
|
||||
gLuaLastHookMod = activeMod;
|
||||
gPcDebug.lastModRun = activeMod;
|
||||
|
||||
|
|
@ -62,7 +66,8 @@ int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct M
|
|||
|
||||
lua_profiler_stop_counter(activeMod);
|
||||
|
||||
gLuaActiveMod = prev;
|
||||
gLuaActiveMod = prevActiveMod;
|
||||
gLuaActiveModFile = prevActiveModFile;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +136,7 @@ static bool smlua_call_event_hooks_on_hud_render(void (*resetFunc)(void), bool r
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[hookType]);
|
||||
} else {
|
||||
hookResult = true;
|
||||
|
|
@ -170,7 +175,7 @@ bool smlua_call_event_hooks_HOOK_ON_NAMETAGS_RENDER(s32 playerIndex, Vec3f pos,
|
|||
smlua_new_vec3f(pos);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) {
|
||||
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
|
||||
LOG_LUA("Failed to call the callback for hook %s", sLuaHookedEventTypeName[HOOK_ON_NAMETAGS_RENDER]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -223,6 +228,7 @@ struct LuaHookedMarioAction {
|
|||
u32 interactionType;
|
||||
int actionHookRefs[ACTION_HOOK_MAX];
|
||||
struct Mod* mod;
|
||||
struct ModFile* modFile;
|
||||
};
|
||||
|
||||
#define MAX_HOOKED_ACTIONS (ACT_NUM_GROUPS * ACT_NUM_ACTIONS_PER_GROUP)
|
||||
|
|
@ -311,6 +317,7 @@ int smlua_hook_mario_action(lua_State* L) {
|
|||
hooked->action = action;
|
||||
hooked->interactionType = interactionType;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
sHookedMarioActionsCount++;
|
||||
return 1;
|
||||
|
|
@ -334,7 +341,7 @@ bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState*
|
|||
lua_remove(L, -2);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod)) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod, hook->modFile)) {
|
||||
LOG_LUA("Failed to call the action callback: %u", m->action);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -381,6 +388,7 @@ struct LuaHookedBehavior {
|
|||
bool replace;
|
||||
bool luaBehavior;
|
||||
struct Mod* mod;
|
||||
struct ModFile* modFile;
|
||||
};
|
||||
|
||||
#define MAX_HOOKED_BEHAVIORS 1024
|
||||
|
|
@ -474,6 +482,7 @@ int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) {
|
|||
hooked->replace = true;
|
||||
hooked->luaBehavior = false;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
sHookedBehaviorsCount++;
|
||||
|
||||
|
|
@ -620,6 +629,7 @@ int smlua_hook_behavior(lua_State* L) {
|
|||
hooked->replace = replaceBehavior;
|
||||
hooked->luaBehavior = true;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
sHookedBehaviorsCount++;
|
||||
|
||||
|
|
@ -677,7 +687,7 @@ bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* ob
|
|||
smlua_push_object(L, LOT_OBJECT, object, NULL);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hooked->mod)) {
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hooked->mod, hooked->modFile)) {
|
||||
LOG_LUA("Failed to call the behavior callback: %u", hooked->behaviorId);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -698,6 +708,7 @@ struct LuaHookedChatCommand {
|
|||
char* description;
|
||||
int reference;
|
||||
struct Mod* mod;
|
||||
struct ModFile* modFile;
|
||||
};
|
||||
|
||||
#define MAX_HOOKED_CHAT_COMMANDS 512
|
||||
|
|
@ -742,6 +753,7 @@ int smlua_hook_chat_command(lua_State* L) {
|
|||
hooked->description = strdup(description);
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
sHookedChatCommandsCount++;
|
||||
return 1;
|
||||
|
|
@ -805,7 +817,7 @@ bool smlua_call_chat_command_hook(char* command) {
|
|||
lua_pushstring(L, params);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod)) {
|
||||
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod, hook->modFile)) {
|
||||
LOG_LUA("Failed to call the chat command callback: %s", command);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1108,6 +1120,7 @@ int smlua_hook_mod_menu_text(lua_State* L) {
|
|||
hooked->sliderMax = 0;
|
||||
hooked->reference = 0;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
lua_pushinteger(L, gHookedModMenuElementsCount);
|
||||
gHookedModMenuElementsCount++;
|
||||
|
|
@ -1146,6 +1159,7 @@ int smlua_hook_mod_menu_button(lua_State* L) {
|
|||
hooked->sliderMax = 0;
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
lua_pushinteger(L, gHookedModMenuElementsCount);
|
||||
gHookedModMenuElementsCount++;
|
||||
|
|
@ -1190,6 +1204,7 @@ int smlua_hook_mod_menu_checkbox(lua_State* L) {
|
|||
hooked->sliderMax = 0;
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
lua_pushinteger(L, gHookedModMenuElementsCount);
|
||||
gHookedModMenuElementsCount++;
|
||||
|
|
@ -1246,6 +1261,7 @@ int smlua_hook_mod_menu_slider(lua_State* L) {
|
|||
hooked->sliderMax = sliderMax;
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
lua_pushinteger(L, gHookedModMenuElementsCount);
|
||||
gHookedModMenuElementsCount++;
|
||||
|
|
@ -1297,6 +1313,7 @@ int smlua_hook_mod_menu_inputbox(lua_State* L) {
|
|||
hooked->sliderMax = 0;
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
hooked->modFile = gLuaActiveModFile;
|
||||
|
||||
lua_pushinteger(L, gHookedModMenuElementsCount);
|
||||
gHookedModMenuElementsCount++;
|
||||
|
|
@ -1428,7 +1445,7 @@ void smlua_call_mod_menu_element_hook(struct LuaHookedModMenuElement* hooked, in
|
|||
}
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, params, 1, 0, hooked->mod)) {
|
||||
if (0 != smlua_call_hook(L, params, 1, 0, hooked->mod, hooked->modFile)) {
|
||||
LOG_LUA("Failed to call the mod menu element callback: %s", hooked->name);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1453,6 +1470,7 @@ void smlua_clear_hooks(void) {
|
|||
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[i];
|
||||
hooked->action = 0;
|
||||
hooked->mod = NULL;
|
||||
hooked->modFile = NULL;
|
||||
memset(hooked->actionHookRefs, 0, sizeof(hooked->actionHookRefs));
|
||||
}
|
||||
sHookedMarioActionsCount = 0;
|
||||
|
|
@ -1467,6 +1485,7 @@ void smlua_clear_hooks(void) {
|
|||
|
||||
hooked->reference = 0;
|
||||
hooked->mod = NULL;
|
||||
hooked->modFile = NULL;
|
||||
}
|
||||
sHookedChatCommandsCount = 0;
|
||||
|
||||
|
|
@ -1482,6 +1501,7 @@ void smlua_clear_hooks(void) {
|
|||
hooked->sliderMax = 0;
|
||||
hooked->reference = 0;
|
||||
hooked->mod = NULL;
|
||||
hooked->modFile = NULL;
|
||||
}
|
||||
gHookedModMenuElementsCount = 0;
|
||||
|
||||
|
|
@ -1510,6 +1530,7 @@ void smlua_clear_hooks(void) {
|
|||
hooked->replace = false;
|
||||
hooked->luaBehavior = false;
|
||||
hooked->mod = NULL;
|
||||
hooked->modFile = NULL;
|
||||
}
|
||||
sHookedBehaviorsCount = 0;
|
||||
memset(gLuaMarioActionIndex, 0, sizeof(gLuaMarioActionIndex));
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ struct LuaHookedModMenuElement {
|
|||
u32 sliderMax;
|
||||
int reference;
|
||||
struct Mod* mod;
|
||||
struct ModFile* modFile;
|
||||
};
|
||||
|
||||
extern u32 gLuaMarioActionIndex[];
|
||||
|
|
@ -140,7 +141,7 @@ bool smlua_is_behavior_hooked(const BehaviorScript *behavior);
|
|||
const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id);
|
||||
bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before);
|
||||
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod);
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile);
|
||||
bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue);
|
||||
u32 smlua_get_action_interaction_type(struct MarioState* m);
|
||||
|
||||
|
|
|
|||
180
src/pc/lua/smlua_require.c
Normal file
180
src/pc/lua/smlua_require.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
#include <stdbool.h>
|
||||
#include "smlua.h"
|
||||
#include "pc/mods/mods.h"
|
||||
#include "pc/mods/mods_utils.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
|
||||
|
||||
// table to track loaded modules per mod
|
||||
static void smlua_init_mod_loaded_table(lua_State* L, const char* modPath) {
|
||||
// Create a unique registry key for this mod's loaded table
|
||||
char registryKey[SYS_MAX_PATH + 16];
|
||||
snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", modPath);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, registryKey);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, registryKey);
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ModFile* smlua_find_mod_file(const char* moduleName) {
|
||||
char relativeDir[SYS_MAX_PATH] = "";
|
||||
|
||||
if (!gLuaActiveMod) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gLuaActiveModFile) {
|
||||
path_get_folder(gLuaActiveModFile->relativePath, relativeDir);
|
||||
}
|
||||
|
||||
bool hasRelativeDir = strlen(relativeDir) > 0;
|
||||
|
||||
struct ModFile* bestPick = NULL;
|
||||
int bestRelativeDepth = INT_MAX;
|
||||
int bestTotalDepth = INT_MAX;
|
||||
bool foundRelativeFile = false;
|
||||
|
||||
char luaName[SYS_MAX_PATH] = "";
|
||||
char luacName[SYS_MAX_PATH] = "";
|
||||
snprintf(luaName, SYS_MAX_PATH, "%s.lua", moduleName);
|
||||
snprintf(luacName, SYS_MAX_PATH, "%s.luac", moduleName);
|
||||
|
||||
for (int i = 0; i < gLuaActiveMod->fileCount; i++) {
|
||||
struct ModFile* file = &gLuaActiveMod->files[i];
|
||||
|
||||
// don't consider the currently running file
|
||||
if (file == gLuaActiveModFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// only consider lua files
|
||||
if (!str_ends_with(file->relativePath, ".lua") && !str_ends_with(file->relativePath, ".luac")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for match
|
||||
if (!str_ends_with(file->relativePath, moduleName) && !str_ends_with(file->relativePath, luaName) && !str_ends_with(file->relativePath, luacName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get total path depth
|
||||
int totalDepth = path_depth(file->relativePath);
|
||||
|
||||
// make sure we never load the old-style lua files with require()
|
||||
if (totalDepth < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get relative path depth
|
||||
int relativeDepth = INT_MAX;
|
||||
if (hasRelativeDir && path_is_relative_to(file->relativePath, relativeDir)) {
|
||||
relativeDepth = path_depth(file->relativePath + strlen(relativeDir));
|
||||
foundRelativeFile = true;
|
||||
}
|
||||
|
||||
// pick new best
|
||||
// relative files will always win against absolute files
|
||||
// other than that, shallower files will win
|
||||
if (relativeDepth < bestRelativeDepth || (!foundRelativeFile && totalDepth < bestTotalDepth)) {
|
||||
bestPick = file;
|
||||
bestRelativeDepth = relativeDepth;
|
||||
bestTotalDepth = totalDepth;
|
||||
}
|
||||
}
|
||||
|
||||
return bestPick;
|
||||
}
|
||||
|
||||
static int smlua_custom_require(lua_State* L) {
|
||||
const char* moduleName = luaL_checkstring(L, 1);
|
||||
|
||||
struct Mod* activeMod = gLuaActiveMod;
|
||||
if (!activeMod) {
|
||||
LOG_LUA("require() called outside of mod context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create registry key for this mod's loaded table
|
||||
char registryKey[SYS_MAX_PATH + 16] = "";
|
||||
snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", activeMod->relativePath);
|
||||
|
||||
// get or create the mod's loaded table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, registryKey);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, registryKey);
|
||||
}
|
||||
|
||||
// find the file in mod files
|
||||
struct ModFile* file = smlua_find_mod_file(moduleName);
|
||||
if (!file) {
|
||||
LOG_LUA("module '%s' not found in mod files", moduleName);
|
||||
lua_pop(L, 1); // pop table
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check if module is already loaded
|
||||
lua_getfield(L, -1, file->relativePath);
|
||||
if (!lua_isnil(L, -1)) {
|
||||
// module already loaded, return it
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L, 1); // pop nil value
|
||||
|
||||
// mark module as "loading" to prevent recursion
|
||||
lua_pushboolean(L, 1);
|
||||
lua_setfield(L, -2, file->relativePath);
|
||||
|
||||
// cache the previous mod file
|
||||
struct ModFile* prevModFile = gLuaActiveModFile;
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
// load and execute
|
||||
gLuaActiveModFile = file;
|
||||
smlua_load_script(activeMod, file, activeMod->index, false);
|
||||
gLuaActiveModFile = prevModFile;
|
||||
|
||||
// if the module didn't return anything, use true
|
||||
if (prevTop == lua_gettop(L)) {
|
||||
lua_pushboolean(L, 1);
|
||||
} else if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, 1);
|
||||
}
|
||||
|
||||
// store in loaded table
|
||||
lua_pushvalue(L, -1); // duplicate return value
|
||||
lua_setfield(L, -3, file->relativePath); // loaded[file->relativePath] = return_value
|
||||
|
||||
// clean up stack
|
||||
lua_remove(L, -2);
|
||||
|
||||
return 1; // return the module value
|
||||
}
|
||||
|
||||
void smlua_bind_custom_require(lua_State* L) {
|
||||
// replace the global require function
|
||||
lua_pushcfunction(L, smlua_custom_require);
|
||||
lua_setglobal(L, "require");
|
||||
}
|
||||
|
||||
void smlua_init_require_system(void) {
|
||||
lua_State* L = gLuaState;
|
||||
if (!L) return;
|
||||
|
||||
// initialize the custom require function
|
||||
smlua_bind_custom_require(L);
|
||||
|
||||
// initialize loaded tables for each mod
|
||||
for (int i = 0; i < gActiveMods.entryCount; i++) {
|
||||
struct Mod* mod = gActiveMods.entries[i];
|
||||
smlua_init_mod_loaded_table(L, mod->relativePath);
|
||||
}
|
||||
}
|
||||
9
src/pc/lua/smlua_require.h
Normal file
9
src/pc/lua/smlua_require.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef SMLUA_REQUIRE_H
|
||||
#define SMLUA_REQUIRE_H
|
||||
|
||||
#include "smlua.h"
|
||||
|
||||
void smlua_bind_custom_require(lua_State* L);
|
||||
void smlua_init_require_system(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -143,14 +143,20 @@ static void smlua_sync_table_call_hook(int syncTableIndex, int keyIndex, int pre
|
|||
struct Mod* mod = gActiveMods.entries[modRemoteIndex];
|
||||
|
||||
// call hook
|
||||
struct Mod* prev = gLuaActiveMod;
|
||||
struct Mod* prevActiveMod = gLuaActiveMod;
|
||||
struct ModFile* prevActiveModFile = gLuaActiveModFile;
|
||||
|
||||
gLuaActiveMod = mod;
|
||||
gLuaActiveModFile = NULL;
|
||||
gLuaLastHookMod = mod;
|
||||
gPcDebug.lastModRun = mod;
|
||||
|
||||
if (0 != smlua_pcall(L, 3, 0, 0)) {
|
||||
LOG_LUA_LINE("Failed to call the hook_on_changed callback");
|
||||
}
|
||||
gLuaActiveMod = prev;
|
||||
|
||||
gLuaActiveMod = prevActiveMod;
|
||||
prevActiveModFile = prevActiveModFile;
|
||||
}
|
||||
|
||||
lua_pop(L, 1); // pop _hook_on_changed's value
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <sys/stat.h>
|
||||
#include "mod.h"
|
||||
#include "mods.h"
|
||||
#include "mods_utils.h"
|
||||
|
|
@ -39,9 +40,13 @@ static void mod_activate_bin(struct Mod* mod, struct ModFile* file) {
|
|||
g++;
|
||||
}
|
||||
|
||||
// get mod file index
|
||||
s32 fileIndex = (file - &mod->files[0]);
|
||||
if (fileIndex < 0 || fileIndex >= mod->fileCount) { fileIndex = 0; }
|
||||
|
||||
// Add to custom actors
|
||||
LOG_INFO("Activating DynOS bin: '%s', '%s'", file->cachedPath, geoName);
|
||||
dynos_add_actor_custom(mod->index, file->cachedPath, geoName);
|
||||
dynos_add_actor_custom(mod->index, fileIndex, file->cachedPath, geoName);
|
||||
}
|
||||
|
||||
static void mod_activate_col(struct ModFile* file) {
|
||||
|
|
@ -261,7 +266,7 @@ static struct ModFile* mod_allocate_file(struct Mod* mod, char* relativePath) {
|
|||
return file;
|
||||
}
|
||||
|
||||
static bool mod_load_files_dir(struct Mod* mod, char* fullPath, const char* subDir, const char** fileTypes) {
|
||||
static bool mod_load_files_dir(struct Mod* mod, char* fullPath, const char* subDir, const char** fileTypes, bool recursive) {
|
||||
|
||||
// concat directory
|
||||
char dirPath[SYS_MAX_PATH] = { 0 };
|
||||
|
|
@ -285,15 +290,33 @@ static bool mod_load_files_dir(struct Mod* mod, char* fullPath, const char* subD
|
|||
if (strlen(subDir) > 0) {
|
||||
if (snprintf(relativePath, SYS_MAX_PATH - 1, "%s/%s", subDir, dir->d_name) < 0) {
|
||||
LOG_ERROR("Could not concat %s path!", subDir);
|
||||
closedir(d);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (snprintf(relativePath, SYS_MAX_PATH - 1, "%s", dir->d_name) < 0) {
|
||||
LOG_ERROR("Could not concat %s path!", subDir);
|
||||
closedir(d);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a directory
|
||||
struct stat st = { 0 };
|
||||
if (recursive && stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
// Skip . and .. directories
|
||||
if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Recursively process subdirectory
|
||||
if (!mod_load_files_dir(mod, fullPath, relativePath, fileTypes, recursive)) {
|
||||
closedir(d);
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// only consider certain file types
|
||||
bool fileTypeMatch = false;
|
||||
const char** ft = fileTypes;
|
||||
|
|
@ -325,37 +348,37 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
|||
// deal with mod directory
|
||||
{
|
||||
const char* fileTypes[] = { ".lua", ".luac", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "", fileTypes, true)) { return false; }
|
||||
}
|
||||
|
||||
// deal with actors directory
|
||||
{
|
||||
const char* fileTypes[] = { ".bin", ".col", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "actors", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "actors", fileTypes, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with behaviors directory
|
||||
{
|
||||
const char* fileTypes[] = { ".bhv", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "data", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "data", fileTypes, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with textures directory
|
||||
{
|
||||
const char* fileTypes[] = { ".tex", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "textures", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "textures", fileTypes, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with levels directory
|
||||
{
|
||||
const char* fileTypes[] = { ".lvl", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "levels", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "levels", fileTypes, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with sound directory
|
||||
{
|
||||
const char* fileTypes[] = { ".m64", ".mp3", ".aiff", ".ogg", NULL };
|
||||
if (!mod_load_files_dir(mod, fullPath, "sound", fileTypes)) { return false; }
|
||||
if (!mod_load_files_dir(mod, fullPath, "sound", fileTypes, false)) { return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,20 @@ void path_get_folder(char* path, char* outpath) {
|
|||
*o = '\0';
|
||||
}
|
||||
|
||||
int path_depth(const char* path) {
|
||||
int depth = 0;
|
||||
for (; *path; path++) {
|
||||
if (*path == '/' || *path == '\\') {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
bool path_is_relative_to(const char* fullPath, const char* baseDir) {
|
||||
return strncmp(fullPath, baseDir, strlen(baseDir)) == 0;
|
||||
}
|
||||
|
||||
bool directory_sanity_check(struct dirent* dir, char* dirPath, char* outPath) {
|
||||
// skip non-portable filenames
|
||||
if (!fs_sys_filename_is_portable(dir->d_name)) { return false; }
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ void normalize_path(char* path);
|
|||
bool concat_path(char* destination, char* path, char* fname);
|
||||
char* path_basename(char* path);
|
||||
void path_get_folder(char* path, char* outpath);
|
||||
int path_depth(const char* path);
|
||||
bool path_is_relative_to(const char* fullPath, const char* baseDir);
|
||||
bool directory_sanity_check(struct dirent* dir, char* dirPath, char* outPath);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue