mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-29 15:08:50 -04:00
127 lines
3.8 KiB
Lua
127 lines
3.8 KiB
Lua
local Importers = require("src.import.Importers")
|
|
local SaveData = require("src.core.SaveData")
|
|
|
|
local AssetPacks = {}
|
|
|
|
AssetPacks.MAX_READ_BYTES = Importers.MAX_ENTRY_BYTES
|
|
|
|
local function specs(manifest)
|
|
local out = {}
|
|
for _, list in ipairs({ (manifest and manifest.required_assets) or {},
|
|
(manifest and manifest.optional_assets) or {} }) do
|
|
for _, spec in ipairs(list) do
|
|
out[spec.importer .. "/" .. spec.pack] = spec
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
AssetPacks.specs = function(manifest)
|
|
local out = {}
|
|
for _, spec in ipairs((manifest and manifest.required_assets) or {}) do
|
|
out[#out + 1] = spec
|
|
end
|
|
for _, spec in ipairs((manifest and manifest.optional_assets) or {}) do
|
|
out[#out + 1] = spec
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function copyEntry(id, entry)
|
|
return { id = id, file = entry.file, size = entry.size,
|
|
width = entry.width, height = entry.height, frames = entry.frames,
|
|
seconds = entry.seconds, note = entry.note }
|
|
end
|
|
|
|
function AssetPacks.new(manifest, fs)
|
|
local declared = specs(manifest)
|
|
local packFs = SaveData.persistenceFs(fs) or fs
|
|
local api = {}
|
|
|
|
local function specFor(importerId, packId)
|
|
local spec = declared[tostring(importerId) .. "/" .. tostring(packId)]
|
|
if not spec then
|
|
return nil, ("undeclared asset pack: %s/%s")
|
|
:format(tostring(importerId), tostring(packId))
|
|
end
|
|
return spec
|
|
end
|
|
|
|
local function resolved(importerId, packId)
|
|
local spec, err = specFor(importerId, packId)
|
|
if not spec then return nil, err end
|
|
return Importers.resolve(spec, packFs)
|
|
end
|
|
|
|
function api:list()
|
|
local out = {}
|
|
for _, spec in ipairs(AssetPacks.specs(manifest)) do
|
|
local pack = Importers.resolve(spec, packFs)
|
|
out[#out + 1] = {
|
|
importer = spec.importer,
|
|
pack = spec.pack,
|
|
version = pack and pack.version or nil,
|
|
kind = pack and pack.kind or nil,
|
|
required = spec.required ~= false,
|
|
installed = pack ~= nil,
|
|
}
|
|
end
|
|
return out
|
|
end
|
|
|
|
function api:info(importerId, packId)
|
|
local pack, err = resolved(importerId, packId)
|
|
if not pack then return nil, err end
|
|
local count = 0
|
|
for _ in pairs(pack.entries) do count = count + 1 end
|
|
return { importer = pack.importer, pack = pack.pack, kind = pack.kind,
|
|
version = pack.version, entries = count, source = pack.source.name }
|
|
end
|
|
|
|
function api:entries(importerId, packId)
|
|
local pack, err = resolved(importerId, packId)
|
|
if not pack then return nil, err end
|
|
local out = {}
|
|
for id, entry in pairs(pack.entries) do
|
|
out[#out + 1] = copyEntry(id, entry)
|
|
end
|
|
table.sort(out, function(a, b) return a.id < b.id end)
|
|
return out
|
|
end
|
|
|
|
function api:entry(importerId, packId, entryId)
|
|
local pack, err = resolved(importerId, packId)
|
|
if not pack then return nil, err end
|
|
local entry = pack.entries[entryId]
|
|
if not entry then
|
|
return nil, "no such pack entry: " .. tostring(entryId)
|
|
end
|
|
return copyEntry(entryId, entry)
|
|
end
|
|
|
|
function api:read(importerId, packId, entryId)
|
|
local pack, err = resolved(importerId, packId)
|
|
if not pack then return nil, err end
|
|
local entry = pack.entries[entryId]
|
|
if not entry then
|
|
return nil, "no such pack entry: " .. tostring(entryId)
|
|
end
|
|
if entry.size > AssetPacks.MAX_READ_BYTES then
|
|
return nil, "pack entry exceeds the 8 MiB read limit"
|
|
end
|
|
local path, pathErr = Importers.assetPath(pack.importer, pack.pack, entry.file)
|
|
if not path then return nil, pathErr end
|
|
if not (packFs and packFs.read) then
|
|
return nil, "pack reads are unavailable"
|
|
end
|
|
local bytes = packFs.read(path)
|
|
if type(bytes) ~= "string" then return nil, "pack entry is missing" end
|
|
if #bytes ~= entry.size then return nil, "pack entry size does not match" end
|
|
return bytes
|
|
end
|
|
|
|
return api
|
|
end
|
|
|
|
return AssetPacks
|