mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-15 15:51:17 +02:00
Merge pull request #1072 from dlloa/gen1recomp-issue-28
Export versioned mod option schemas for native launchers
This commit is contained in:
@@ -23,6 +23,8 @@ local Loader = {}
|
||||
Loader.__index = Loader
|
||||
|
||||
local MOD_STATE_FILE = "mod_state.lua" -- legacy migration only
|
||||
local OPTION_SCHEMAS_FILENAME = "mod_option_schemas.json"
|
||||
local OPTION_SCHEMAS_VERSION = 1
|
||||
|
||||
-- The working tree's engine version is the "0.0.0-dev" placeholder that CI
|
||||
-- restamps into the packed game.love (src/core/Version.lua:7), and it sorts
|
||||
@@ -339,6 +341,57 @@ function Loader:_saveState()
|
||||
SaveData.saveOptions(options, self.fs)
|
||||
end
|
||||
|
||||
-- Export the runtime option schemas after mod entry chunks have run. This
|
||||
-- is an optional, data-only handoff for native launchers: they must not run
|
||||
-- arbitrary mod code before boot just to discover settings. The snapshot is
|
||||
-- deliberately written beside options.lua so every platform's native shell
|
||||
-- can use the same filesystem contract.
|
||||
function Loader:_writeOptionSchemas()
|
||||
if not self.fs.write then return end
|
||||
|
||||
local mods = {}
|
||||
for id, mod in pairs(self.mods) do
|
||||
if mod.enabled and not mod.failed then
|
||||
local schema = self.optionSchemas[id]
|
||||
-- Keep the legacy manifest options_schema path visible to native
|
||||
-- consumers too. ManagerState loads this same data-only chunk on
|
||||
-- demand; using it here means older mods do not need to migrate to
|
||||
-- mod.options:define just to appear in a launcher settings screen.
|
||||
if schema == nil and mod.manifest.options_schema and self.fs.load then
|
||||
local chunk = self.fs.load(mod.path .. "/" .. mod.manifest.options_schema)
|
||||
if chunk then
|
||||
local ok, rows = pcall(chunk)
|
||||
if ok and type(rows) == "table" then schema = rows end
|
||||
end
|
||||
end
|
||||
if schema ~= nil then
|
||||
mods[id] = schema
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Do not create storage on a fresh mod-free boot, but do overwrite an old
|
||||
-- snapshot when the current boot has no schemas so disabled/failed mods do
|
||||
-- not leave stale native settings rows behind.
|
||||
if next(mods) == nil
|
||||
and not (self.fs.getInfo and self.fs.getInfo(OPTION_SCHEMAS_FILENAME)) then
|
||||
return
|
||||
end
|
||||
|
||||
local ok, encoded = pcall(Json.encode, {
|
||||
schema_version = OPTION_SCHEMAS_VERSION,
|
||||
mods = mods,
|
||||
})
|
||||
if not ok then
|
||||
Logger.warn("mod option schema export: failed to encode: %s", tostring(encoded))
|
||||
return
|
||||
end
|
||||
local written, err = self.fs.write(OPTION_SCHEMAS_FILENAME, encoded)
|
||||
if not written then
|
||||
Logger.warn("mod option schema export: failed to write: %s", tostring(err))
|
||||
end
|
||||
end
|
||||
|
||||
function Loader:setEnabled(id, enabled)
|
||||
if not self.mods[id] then return false end
|
||||
self.disabled[id] = not enabled
|
||||
@@ -1421,6 +1474,7 @@ function Loader:load(data)
|
||||
-- which resolves every path to itself (14 §asset resolution).
|
||||
Assets.installLoader(self)
|
||||
self.events:emit("mods.loaded", { loader = self, data = data })
|
||||
self:_writeOptionSchemas()
|
||||
self.initialized = true
|
||||
return #self.errors == 0
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user