199 lines
4.8 KiB
Go
199 lines
4.8 KiB
Go
package topdata
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func importLegacyVFXPersistent(referenceBuilderDir, dataDir string, legacyTLK *legacyTLKData) (int, error) {
|
|
_ = legacyTLK
|
|
if strings.TrimSpace(referenceBuilderDir) == "" {
|
|
return 0, nil
|
|
}
|
|
|
|
legacyDir := filepath.Join(referenceBuilderDir, "data", "vfx_persistent")
|
|
if _, err := os.Stat(legacyDir); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return 0, nil
|
|
}
|
|
return 0, err
|
|
}
|
|
|
|
targetDir := filepath.Join(dataDir, "vfx_persistent")
|
|
targetBasePath := filepath.Join(targetDir, "base.json")
|
|
targetLockPath := filepath.Join(targetDir, "lock.json")
|
|
targetModulesDir := filepath.Join(targetDir, "modules")
|
|
targetModulePath := filepath.Join(targetModulesDir, "freeformaoes.json")
|
|
if fileExists(targetBasePath) && fileExists(targetLockPath) && fileExists(targetModulePath) {
|
|
baseObj, baseErr := loadJSONObject(targetBasePath)
|
|
lockObj, lockErr := loadJSONObject(targetLockPath)
|
|
if baseErr == nil && lockErr == nil && vfxPersistentImportComplete(baseObj, lockObj) {
|
|
legacyModulePaths, err := collectJSONRelativePaths(filepath.Join(legacyDir, "modules"))
|
|
if err == nil {
|
|
targetModulePaths, err := collectJSONRelativePaths(targetModulesDir)
|
|
if err == nil && equalStringSlices(legacyModulePaths, targetModulePaths) {
|
|
return 0, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
baseObj, err := loadJSONObject(filepath.Join(legacyDir, "base.json"))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
lockObj, err := synthesizeVFXPersistentKeys(baseObj)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
legacyLockObj, err := loadJSONObject(filepath.Join(legacyDir, "lock.json"))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
for key, value := range legacyLockObj {
|
|
lockObj[key] = value
|
|
}
|
|
if err := os.MkdirAll(targetModulesDir, 0o755); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
updated := 0
|
|
for _, write := range []struct {
|
|
path string
|
|
obj map[string]any
|
|
}{
|
|
{path: targetBasePath, obj: baseObj},
|
|
{path: targetLockPath, obj: lockObj},
|
|
} {
|
|
changed, err := writeJSONObjectIfChanged(write.path, write.obj)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if changed {
|
|
updated++
|
|
}
|
|
}
|
|
|
|
moduleRelPaths, err := collectJSONRelativePaths(filepath.Join(legacyDir, "modules"))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
for _, relPath := range moduleRelPaths {
|
|
moduleObj, err := loadJSONObject(filepath.Join(legacyDir, "modules", filepath.FromSlash(relPath)))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
targetPath := filepath.Join(targetModulesDir, filepath.FromSlash(relPath))
|
|
if err := os.MkdirAll(filepath.Dir(targetPath), 0o755); err != nil {
|
|
return 0, err
|
|
}
|
|
changed, err := writeJSONObjectIfChanged(targetPath, moduleObj)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if changed {
|
|
updated++
|
|
}
|
|
}
|
|
|
|
targetModulePaths, err := collectJSONRelativePaths(targetModulesDir)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
legacyModules := make(map[string]struct{}, len(moduleRelPaths))
|
|
for _, relPath := range moduleRelPaths {
|
|
legacyModules[relPath] = struct{}{}
|
|
}
|
|
for _, relPath := range targetModulePaths {
|
|
if _, ok := legacyModules[relPath]; ok {
|
|
continue
|
|
}
|
|
if err := os.Remove(filepath.Join(targetModulesDir, filepath.FromSlash(relPath))); err != nil && !os.IsNotExist(err) {
|
|
return 0, err
|
|
}
|
|
updated++
|
|
}
|
|
|
|
return updated, nil
|
|
}
|
|
|
|
func vfxPersistentImportComplete(baseObj, lockObj map[string]any) bool {
|
|
if !vfxPersistentRowsHaveKeys(baseObj) {
|
|
return false
|
|
}
|
|
expected := map[string]int{
|
|
"vfx_persistent:blankradius5": 47,
|
|
"vfx_persistent:blankradius10": 48,
|
|
"vfx_persistent:blankradius15": 49,
|
|
"vfx_persistent:blankradius20": 50,
|
|
"vfx_persistent:blankradius25": 51,
|
|
"vfx_persistent:blankradius30": 52,
|
|
}
|
|
for key, want := range expected {
|
|
raw, ok := lockObj[key]
|
|
if !ok {
|
|
return false
|
|
}
|
|
got, err := asInt(raw)
|
|
if err != nil || got != want {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func synthesizeVFXPersistentKeys(baseObj map[string]any) (map[string]any, error) {
|
|
rawRows, ok := baseObj["rows"].([]any)
|
|
if !ok {
|
|
return map[string]any{}, nil
|
|
}
|
|
lockObj := map[string]any{}
|
|
for _, raw := range rawRows {
|
|
row, ok := raw.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
label, _ := row["LABEL"].(string)
|
|
if label == "" {
|
|
continue
|
|
}
|
|
key := "vfx_persistent:" + strings.ToLower(label)
|
|
row["key"] = key
|
|
if rawID, ok := row["id"]; ok {
|
|
lockObj[key] = rawID
|
|
}
|
|
}
|
|
return lockObj, nil
|
|
}
|
|
|
|
func vfxPersistentRowsHaveKeys(baseObj map[string]any) bool {
|
|
rawRows, ok := baseObj["rows"].([]any)
|
|
if !ok {
|
|
return false
|
|
}
|
|
for _, raw := range rawRows {
|
|
row, ok := raw.(map[string]any)
|
|
if !ok {
|
|
return false
|
|
}
|
|
key, _ := row["key"].(string)
|
|
if key == "" {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func equalStringSlices(left, right []string) bool {
|
|
if len(left) != len(right) {
|
|
return false
|
|
}
|
|
for i := range left {
|
|
if left[i] != right[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|