Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Lua/ModLoader.lua
2022-10-30 16:34:01 -03:00

153 lines
4.5 KiB
Lua

local LUA_MOD_REQUIRE_PATH = "/Lua/?.lua"
local LUA_MOD_AUTORUN_PATH = "/Lua/Autorun"
local LUA_MOD_FORCEDAUTORUN_PATH = "/Lua/ForcedAutorun"
local function EndsWith(str, suffix)
return str:sub(-string.len(suffix)) == suffix
end
local function GetFileName(file)
return file:match("^.+/(.+)$")
end
local function ExecuteProtected(s, folder)
loadfile(s)(folder)
end
local function RunFolder(folder, rootFolder, package)
local search = File.DirSearch(folder)
for i = 1, #search, 1 do
local s = search[i]:gsub("\\", "/")
if EndsWith(s, ".lua") then
local time = os.clock()
local ok, result = pcall(ExecuteProtected, s, rootFolder)
local diff = os.clock() - time
print(string.format(" - %s (Took %.5fms)", GetFileName(s), diff))
if not ok then
printerror(result)
end
end
end
end
local function AssertTypes(expectedTypes, ...)
local args = table.pack(...)
assert(
#args == #expectedTypes,
string.format(
"Assertion failed: incorrect number of args\n\texpected = %s\n\tgot = %s",
#expectedTypes, #args
)
)
for i = 1, #args do
local arg = args[i]
local expectedType = expectedTypes[i]
assert(
type(arg) == expectedType,
string.format(
"Assertion failed: incorrect argument type (arg #%d)\n\texpected = %s\n\tgot = %s",
i, expectedType, type(arg)
)
)
end
end
local function ExecutionQueue()
local queue = {}
local function processQueueFIFO()
while queue[1] ~= nil do
local folder, rootFolder, package = table.unpack(table.remove(queue, 1))
print(string.format("%s %s", package.Name, package.ModVersion))
RunFolder(folder, rootFolder, package)
end
end
local function queueExecutionFIFO(...)
AssertTypes({ 'string', 'string', 'userdata' }, ...)
table.insert(queue, table.pack(...))
end
return queueExecutionFIFO, processQueueFIFO
end
local QueueAutorun, ProcessAutorun = ExecutionQueue()
local QueueForcedAutorun, ProcessForcedAutorun = ExecutionQueue()
local function ProcessPackages(packages, fn)
for pkg in packages do
if pkg then
local pkgPath = pkg.Path
:gsub("\\", "/")
:gsub("/filelist.xml", "")
fn(pkg, pkgPath)
end
end
end
ProcessPackages(
ContentPackageManager.EnabledPackages.All,
function(pkg, pkgPath)
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local autorunPath = pkgPath .. LUA_MOD_AUTORUN_PATH
if File.DirectoryExists(autorunPath) then
QueueAutorun(autorunPath, pkgPath, pkg)
end
end
)
-- we don't want to execute workshop ForcedAutorun if we have a local Package
local executedLocalPackages = {}
ProcessPackages(
ContentPackageManager.EnabledPackages.All,
function(pkg, pkgPath)
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH
if File.DirectoryExists(forcedAutorunPath) then
QueueForcedAutorun(forcedAutorunPath, pkgPath, pkg)
executedLocalPackages[pkg.Name] = true
end
end
)
ProcessPackages(
ContentPackageManager.LocalPackages,
function(pkg, pkgPath)
if not executedLocalPackages[pkg.Name] then
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH
if File.DirectoryExists(forcedAutorunPath) then
QueueForcedAutorun(forcedAutorunPath, pkgPath, pkg)
executedLocalPackages[pkg.Name] = true
end
end
end
)
ProcessPackages(
ContentPackageManager.AllPackages,
function(pkg, pkgPath)
if not executedLocalPackages[pkg.Name] then
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH
if File.DirectoryExists(forcedAutorunPath) then
QueueForcedAutorun(forcedAutorunPath, pkgPath, pkg)
end
end
end
)
setmodulepaths(package.path)
setmodulepaths = nil
ProcessAutorun()
ProcessForcedAutorun()
Hook.Add("stop", "luaSetup.stop", function()
print("Stopping Lua...")
end)
Hook.Call("loaded")