mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-04-26 12:01:43 +00:00
Allowed more extensions to be required and return their file content as strings in require
This commit is contained in:
parent
aa8e01072a
commit
093d179408
2 changed files with 130 additions and 37 deletions
|
|
@ -65,6 +65,42 @@ void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* fi
|
|||
lua_pop(L, 1); // pop loaded table
|
||||
}
|
||||
|
||||
static void smlua_push_file_contents(lua_State* L, struct ModFile* file) {
|
||||
if (!file->cachedPath) {
|
||||
LOG_LUA_LINE("File '%s' has no cachedPath", file->relativePath);
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* f = fopen(file->cachedPath, "rb");
|
||||
if (!f) {
|
||||
LOG_LUA_LINE("Failed to open file '%s'", file->cachedPath);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if (size < 0) {
|
||||
fclose(f);
|
||||
LOG_LUA_LINE("Invalid size for file '%s'", file->cachedPath);
|
||||
return;
|
||||
}
|
||||
|
||||
char* buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
fclose(f);
|
||||
LOG_LUA_LINE("Ran out of memory reading file '%s'", file->cachedPath);
|
||||
return;
|
||||
}
|
||||
|
||||
fread(buffer, 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
lua_pushlstring(L, buffer, size);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static struct ModFile* smlua_find_mod_file(const char* moduleName) {
|
||||
char basePath[SYS_MAX_PATH] = "";
|
||||
char absolutePath[SYS_MAX_PATH] = "";
|
||||
|
|
@ -112,6 +148,70 @@ static struct ModFile* smlua_find_mod_file(const char* moduleName) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *REQUIRE_FILE_ALLOWED_EXTENSIONS[] = {
|
||||
".txt", ".json", ".ini", ".sav", // text
|
||||
".bin", ".col", // actors
|
||||
".bhv", // behaviors
|
||||
".tex", ".png", // textures
|
||||
".lvl", // levels
|
||||
".m64", ".aiff", ".mp3", ".ogg", // audio
|
||||
NULL
|
||||
};
|
||||
|
||||
static const int REQUIRE_FILE_ALLOWED_EXTENSION_COUNT = sizeof(REQUIRE_FILE_ALLOWED_EXTENSIONS) / sizeof(REQUIRE_FILE_ALLOWED_EXTENSIONS[0]);
|
||||
|
||||
static struct ModFile* smlua_find_file(const char* fileName) {
|
||||
char filePath[SYS_MAX_PATH] = "";
|
||||
char basePath[SYS_MAX_PATH] = "";
|
||||
char absolutePath[SYS_MAX_PATH] = "";
|
||||
char normalizedRelative[SYS_MAX_PATH] = "";
|
||||
strcpy(filePath, fileName);
|
||||
normalize_path(filePath);
|
||||
|
||||
if (!gLuaActiveMod) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *lastSlash = strrchr(fileName, '/');
|
||||
const char *lastDot = strrchr(fileName, '.');
|
||||
|
||||
// only consider files with an allowed extension
|
||||
if (lastDot > lastSlash) {
|
||||
bool allowedExtension = false;
|
||||
for (int i = 0; i < REQUIRE_FILE_ALLOWED_EXTENSION_COUNT; i++) {
|
||||
if (path_ends_with(fileName, REQUIRE_FILE_ALLOWED_EXTENSIONS[i])) {
|
||||
allowedExtension = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allowedExtension) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// get the directory of the current file
|
||||
if (gLuaActiveModFile) {
|
||||
path_get_folder(gLuaActiveModFile->relativePath, basePath);
|
||||
}
|
||||
|
||||
// resolve fileName to a path relative to mod root
|
||||
resolve_relative_path(basePath, fileName, absolutePath);
|
||||
|
||||
// since mods' relativePaths are relative to the mod's root, we can do a direct comparison
|
||||
for (int i = 0; i < gLuaActiveMod->fileCount; i++) {
|
||||
struct ModFile* file = &gLuaActiveMod->files[i];
|
||||
|
||||
// check for match, normalizing to system separators
|
||||
strcpy(normalizedRelative, file->relativePath);
|
||||
normalize_path(normalizedRelative);
|
||||
if (!strcmp(normalizedRelative, filePath)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int smlua_custom_require(lua_State* L) {
|
||||
const char* moduleName = luaL_checkstring(L, 1);
|
||||
|
||||
|
|
@ -127,20 +227,37 @@ static int smlua_custom_require(lua_State* L) {
|
|||
}
|
||||
|
||||
// find the file in mod files
|
||||
struct ModFile* file = smlua_find_mod_file(moduleName);
|
||||
struct ModFile* file = smlua_find_file(moduleName);
|
||||
if (!file) {
|
||||
file = smlua_find_mod_file(moduleName);
|
||||
}
|
||||
if (!file) {
|
||||
LOG_LUA_LINE("module '%s' not found in mod files", moduleName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isLuaFile = path_ends_with(file->relativePath, ".lua") || path_ends_with(file->relativePath, ".luac");
|
||||
|
||||
// tag it as a loaded lua module
|
||||
file->isLoadedLuaModule = true;
|
||||
if (isLuaFile) {
|
||||
file->isLoadedLuaModule = true;
|
||||
}
|
||||
|
||||
// check cache first
|
||||
if (smlua_get_cached_module_result(L, activeMod, file)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// return the file content as a string if not a lua file
|
||||
if (!isLuaFile) {
|
||||
s32 prevTop = lua_gettop(L);
|
||||
|
||||
smlua_push_file_contents(L, file);
|
||||
|
||||
smlua_cache_module_result(L, activeMod, file, prevTop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// mark module as "loading" to prevent recursion
|
||||
smlua_mark_module_as_loading(L, activeMod, file);
|
||||
|
||||
|
|
|
|||
|
|
@ -361,41 +361,17 @@ static bool mod_load_files(struct Mod* mod, char* fullPath) {
|
|||
return (mod_allocate_file(mod, mod->relativePath) != NULL);
|
||||
}
|
||||
|
||||
// deal with mod directory
|
||||
{
|
||||
const char* fileTypes[] = { ".lua", ".luac", NULL };
|
||||
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, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with behaviors directory
|
||||
{
|
||||
const char* fileTypes[] = { ".bhv", NULL };
|
||||
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, false)) { return false; }
|
||||
}
|
||||
|
||||
// deal with levels directory
|
||||
{
|
||||
const char* fileTypes[] = { ".lvl", NULL };
|
||||
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, false)) { return false; }
|
||||
}
|
||||
const char* fileTypes[] = {
|
||||
".lua", ".luac", // script
|
||||
".txt", ".json", ".ini", ".sav", "", // text
|
||||
".bin", ".col", // actors
|
||||
".bhv", // behaviors
|
||||
".tex", ".png", // textures
|
||||
".lvl", // levels
|
||||
".m64", ".aiff", ".mp3", ".ogg", // audio
|
||||
NULL
|
||||
};
|
||||
if (!mod_load_files_dir(mod, fullPath, "", fileTypes, true)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue