2018-06-17 02:59:23 +00:00
|
|
|
package doodle
|
|
|
|
|
2018-10-02 17:11:38 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
2019-06-27 22:07:34 +00:00
|
|
|
"runtime"
|
2018-10-02 17:11:38 +00:00
|
|
|
"strings"
|
|
|
|
|
2022-09-24 22:17:25 +00:00
|
|
|
"git.kirsle.net/SketchyMaze/doodle/assets"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/log"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/userdir"
|
2018-10-02 17:11:38 +00:00
|
|
|
)
|
2018-06-17 02:59:23 +00:00
|
|
|
|
2018-10-19 20:31:58 +00:00
|
|
|
// Regexp to match simple filenames for maps and doodads.
|
|
|
|
var reSimpleFilename = regexp.MustCompile(`^([A-Za-z0-9-_.,+ '"\[\](){}]+)$`)
|
2018-10-02 17:11:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
EditFile opens a drawing file (Level or Doodad) in the EditorScene.
|
|
|
|
|
|
|
|
The filename can be one of the following:
|
|
|
|
|
2023-12-09 22:59:31 +00:00
|
|
|
- A simple filename with no path separators in it and/or no file extension.
|
|
|
|
- An absolute path beginning with "/"
|
|
|
|
- A relative path beginning with "./"
|
2018-10-02 17:11:38 +00:00
|
|
|
|
|
|
|
If the filename has an extension (`.level` or `.doodad`), that will disambiguate
|
|
|
|
how to find the file and which mode to start the EditorMode in. Otherwise, the
|
|
|
|
"levels" folder is checked first and the "doodads" folder second.
|
|
|
|
*/
|
|
|
|
func (d *Doodle) EditFile(filename string) error {
|
|
|
|
var absPath string
|
|
|
|
|
|
|
|
// Is it a simple filename?
|
|
|
|
if m := reSimpleFilename.FindStringSubmatch(filename); len(m) > 0 {
|
|
|
|
log.Debug("EditFile: simple filename %s", filename)
|
|
|
|
extension := strings.ToLower(filepath.Ext(filename))
|
2019-06-27 22:07:34 +00:00
|
|
|
|
|
|
|
// Check the system level storage. TODO: no editing of system levels
|
2021-07-14 01:02:57 +00:00
|
|
|
if _, err := assets.Asset("assets/levels/" + filename); err == nil {
|
2019-06-27 22:07:34 +00:00
|
|
|
log.Info("Found level %s in bindata", filename)
|
|
|
|
return d.EditDrawing(filename)
|
|
|
|
}
|
|
|
|
|
2019-06-27 22:59:18 +00:00
|
|
|
// Check the user's levels directory. In WASM this will check in
|
|
|
|
// localStorage.
|
2018-10-19 20:31:58 +00:00
|
|
|
if foundFilename := userdir.ResolvePath(filename, extension, false); foundFilename != "" {
|
2018-10-02 17:11:38 +00:00
|
|
|
log.Info("EditFile: resolved name '%s' to path %s", filename, foundFilename)
|
|
|
|
absPath = foundFilename
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("EditFile: %s: no level or doodad found", filename)
|
|
|
|
}
|
2019-06-27 22:07:34 +00:00
|
|
|
|
2018-10-02 17:11:38 +00:00
|
|
|
} else {
|
|
|
|
log.Debug("Not a simple: %s %+v", filename, reSimpleFilename)
|
2019-06-27 22:07:34 +00:00
|
|
|
|
|
|
|
// WASM: no filesystem access.
|
|
|
|
if runtime.GOOS == "js" {
|
|
|
|
log.Error("EditFile(%s): wasm can't open file paths", filename)
|
|
|
|
return fmt.Errorf("EditFile(%s): wasm can't open file paths", filename)
|
|
|
|
}
|
|
|
|
|
2018-10-02 17:11:38 +00:00
|
|
|
if _, err := os.Stat(filename); !os.IsNotExist(err) {
|
|
|
|
log.Debug("EditFile: verified path %s exists", filename)
|
|
|
|
absPath = filename
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-20 00:23:37 +00:00
|
|
|
return d.EditDrawing(absPath)
|
2018-10-02 17:11:38 +00:00
|
|
|
}
|