57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
package player
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"aego/asset"
|
|
"aego/core/errs"
|
|
"aego/core/log"
|
|
"aego/runtime/bundle"
|
|
"aego/vfs"
|
|
"aego/vfs/memfs"
|
|
)
|
|
|
|
type Bundle struct {
|
|
Manifest []byte
|
|
Files map[string][]byte
|
|
}
|
|
|
|
func MountBytes(b *Bundle) (*bundle.Data, *vfs.VFS, error) {
|
|
d, err := bundle.DecodeData(b.Manifest, bundle.ManifestFile)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
prefix := bundle.Scheme + "://"
|
|
var bad error
|
|
d.Index.Each(func(e *asset.Entry) {
|
|
for _, a := range e.Artifacts {
|
|
rel, ok := strings.CutPrefix(a.Path, prefix)
|
|
if !ok || bad != nil {
|
|
continue
|
|
}
|
|
data, ok := b.Files[rel]
|
|
switch {
|
|
case !ok:
|
|
bad = errs.New(errs.AssetNotMounted, "the game data is missing a file", log.F("path", rel))
|
|
case int64(len(data)) != a.Size:
|
|
bad = errs.New(errs.VFSIO, "a game data file differs from the manifest", log.F("path", rel), log.F("size", len(data)), log.F("want", a.Size))
|
|
}
|
|
}
|
|
})
|
|
if bad != nil {
|
|
return nil, nil, bad
|
|
}
|
|
v, err := vfs.New(vfs.Mount{Scheme: bundle.Scheme, Source: memfs.New(b.Files), ReadOnly: true})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return d, v, nil
|
|
}
|
|
|
|
func (p *Player) mount() (*bundle.Data, *vfs.VFS, error) {
|
|
if p.cfg.Bundle != nil {
|
|
return MountBytes(p.cfg.Bundle)
|
|
}
|
|
return Mount(p.cfg.Data)
|
|
}
|