diff --git a/libs/nativefs/nativefs.lua b/libs/nativefs/nativefs.lua index c6f36e0a6..d3c73e61d 100644 --- a/libs/nativefs/nativefs.lua +++ b/libs/nativefs/nativefs.lua @@ -492,4 +492,52 @@ else end end + +local redirects = {} + +function nativefs.smodsAddRedirect(realPath, lfsPath) + if redirects[realPath] then return false, 'A redirect with path "' .. realPath .. '" already exists' end + redirects[realPath] = lfsPath + return true +end + +local function getRedirectPath(realPath) + for p, r in pairs(redirects) do + local len = #p + local sub = realPath:sub(0, len + 1) + if sub == p then return r end + if sub == p .. "/" then return r .. "/" .. realPath:sub(len + 2) end + end + return false +end + +local function patchSimple(n, l) -- Simple funcions always have the path as the first argument + return function (path, ...) + local red = getRedirectPath(path) + if red then return l(red, ...) end + return n(path, ...) + end +end + +for _, v in ipairs{"newFile", "unmount", "write", "append", "lines", "load", "getDirectoryItems", "getInfo", "createDirectory", "remove", "mount", "newFileData"} do + nativefs[v] = patchSimple(nativefs[v], love.filesystem[v]) +end +nativefs.getDirectoryItemsInfo = patchSimple(nativefs.getDirectoryItemsInfo, getDirectoryItemsInfo) + +do + local nRead = nativefs.read + local lRead = love.filesystem.read + function nativefs.read(containerOrName, nameOrSize, sizeOrNil) + if sizeOrNil then -- Container defined + local red = getRedirectPath(nameOrSize) + if red then return lRead(containerOrName, red, sizeOrNil) end + return nRead(containerOrName, nameOrSize, sizeOrNil) + else + local red = getRedirectPath(containerOrName) + if red then return lRead(red, nameOrSize, sizeOrNil) end + return nRead(containerOrName, nameOrSize, sizeOrNil) + end + end +end + return nativefs diff --git a/src/loader.lua b/src/loader.lua index 3339ac8e4..a48f7fa4a 100644 --- a/src/loader.lua +++ b/src/loader.lua @@ -207,6 +207,11 @@ function loadMods(modsDirectory) elseif depth == 2 and filename == "lovely.toml" and not isDirLovely then isDirLovely = true table.insert(lovely_directories, directory .. "/") + elseif depth == 1 and filename:lower():match("%.zip") then + local loveName = "__SMODS_MOUNTS__/" .. filename + assert(NFS.mount(file_path, loveName)) + assert(NFS.smodsAddRedirect(file_path .. ".mnt", loveName)) + processDirectory(file_path .. ".mnt", depth + 1) elseif filename:lower():match('%.json') and depth > 1 then local json_str = NFS.read(file_path) local parsed, mod = pcall(JSON.decode, json_str)