Fix Sidekick tool startup and path handling
This commit is contained in:
@@ -40,7 +40,7 @@ namespace Synty.SidekickCharacters
|
|||||||
private const string _AUTOSAVE_MISSING_PARTS = "SK_Autosave_missing_parts";
|
private const string _AUTOSAVE_MISSING_PARTS = "SK_Autosave_missing_parts";
|
||||||
private const string _AUTOSAVE_STATE = "SK_Autosave_state";
|
private const string _AUTOSAVE_STATE = "SK_Autosave_state";
|
||||||
private const string _BASE_COLOR_SET_NAME = "Species";
|
private const string _BASE_COLOR_SET_NAME = "Species";
|
||||||
private const string _BASE_COLOR_SET_PATH = "Assets/Synty/SidekickCharacters/Resources/Species";
|
private const string _BASE_COLOR_SET_PATH = "Assets/External/Models/SidekickCharacters/Resources/Species";
|
||||||
private const string _BASE_MESH_NAME = "Meshes/SK_BaseModel";
|
private const string _BASE_MESH_NAME = "Meshes/SK_BaseModel";
|
||||||
private const string _BASE_MATERIAL_NAME = "Materials/M_BaseMaterial";
|
private const string _BASE_MATERIAL_NAME = "Materials/M_BaseMaterial";
|
||||||
private const string _BLEND_GENDER_NAME = "masculineFeminine";
|
private const string _BLEND_GENDER_NAME = "masculineFeminine";
|
||||||
@@ -121,7 +121,7 @@ namespace Synty.SidekickCharacters
|
|||||||
private bool _showAllColourProperties = false;
|
private bool _showAllColourProperties = false;
|
||||||
private float _bodyTypeBlendValue;
|
private float _bodyTypeBlendValue;
|
||||||
private bool _loadingCharacter = false;
|
private bool _loadingCharacter = false;
|
||||||
private bool _loadingContent = true;
|
private bool _loadingContent = false;
|
||||||
private Image _loadingImage;
|
private Image _loadingImage;
|
||||||
private ObjectField _materialField;
|
private ObjectField _materialField;
|
||||||
private float _musclesBlendValue;
|
private float _musclesBlendValue;
|
||||||
@@ -192,7 +192,7 @@ namespace Synty.SidekickCharacters
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensures we release the file lock on the database
|
// ensures we release the file lock on the database
|
||||||
_dbManager.CloseConnection();
|
_dbManager?.CloseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
@@ -211,7 +211,7 @@ namespace Synty.SidekickCharacters
|
|||||||
/// <inheritdoc cref="Update" />
|
/// <inheritdoc cref="Update" />
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (_loadingContent)
|
if (_loadingContent && _loadingImage != null)
|
||||||
{
|
{
|
||||||
Vector3 rotation = _loadingImage.transform.rotation.eulerAngles;
|
Vector3 rotation = _loadingImage.transform.rotation.eulerAngles;
|
||||||
rotation += new Vector3(0, 0, 0.5f * Time.deltaTime);
|
rotation += new Vector3(0, 0, 0.5f * Time.deltaTime);
|
||||||
@@ -473,6 +473,7 @@ namespace Synty.SidekickCharacters
|
|||||||
// if we still can't connect, something's gone wrong, don't keep building the GUI
|
// if we still can't connect, something's gone wrong, don't keep building the GUI
|
||||||
if (_dbManager?.GetCurrentDbConnection() == null)
|
if (_dbManager?.GetCurrentDbConnection() == null)
|
||||||
{
|
{
|
||||||
|
_loadingContent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1814,7 +1815,12 @@ namespace Synty.SidekickCharacters
|
|||||||
|
|
||||||
documentationButton.clickable.clicked += delegate
|
documentationButton.clickable.clicked += delegate
|
||||||
{
|
{
|
||||||
Application.OpenURL("file:Assets/Synty/SidekickCharacters/Documentation/SidekickCharacters_UserGuide.pdf");
|
string documentationPath = Path.Combine(DatabaseManager.GetPackageRootAbsolutePath() ?? string.Empty, "Documentation", "SidekickCharacters_UserGuide.pdf");
|
||||||
|
documentationPath = Path.GetFullPath(documentationPath);
|
||||||
|
if (File.Exists(documentationPath))
|
||||||
|
{
|
||||||
|
Application.OpenURL("file:" + documentationPath);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Button storeButton = new Button
|
Button storeButton = new Button
|
||||||
@@ -1919,7 +1925,8 @@ namespace Synty.SidekickCharacters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void SaveColorSet()
|
private void SaveColorSet()
|
||||||
{
|
{
|
||||||
string path = Path.Combine(_BASE_COLOR_SET_PATH, _currentSpecies.Name);
|
string baseColorSetPath = DatabaseManager.GetPackageAssetPath("Resources", "Species") ?? _BASE_COLOR_SET_PATH;
|
||||||
|
string path = Path.Combine(baseColorSetPath, _currentSpecies.Name);
|
||||||
path = Path.Combine(path, _currentColorSet.Name.Replace(" ", "_"));
|
path = Path.Combine(path, _currentColorSet.Name.Replace(" ", "_"));
|
||||||
|
|
||||||
SaveTexturesToDisk(path);
|
SaveTexturesToDisk(path);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Synty.SidekickCharacters
|
|||||||
private const string _GIT_DB_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/SidekicksDatabase.unitypackage";
|
private const string _GIT_DB_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/SidekicksDatabase.unitypackage";
|
||||||
private const string _PACKAGE_CACHE = "Assets/DownloadCache/Sidekicks.unitypackage";
|
private const string _PACKAGE_CACHE = "Assets/DownloadCache/Sidekicks.unitypackage";
|
||||||
private const string _DB_PACKAGE_CACHE = "Assets/DownloadCache/SidekicksDatabase.unitypackage";
|
private const string _DB_PACKAGE_CACHE = "Assets/DownloadCache/SidekicksDatabase.unitypackage";
|
||||||
private const string _VERSION_FILE = "Assets/Synty/SidekickCharacters/Scripts/Editor/version.txt";
|
private const string _VERSION_FILE_NAME = "version.txt";
|
||||||
private const string _VERSION_TAG = "\"tag_name\":";
|
private const string _VERSION_TAG = "\"tag_name\":";
|
||||||
private const string _VERSION_KEY = "sk_current_tool_version";
|
private const string _VERSION_KEY = "sk_current_tool_version";
|
||||||
private const string _SIDEKICK_TOOL_MENU_ITEM = "Synty/Sidekick Character Tool";
|
private const string _SIDEKICK_TOOL_MENU_ITEM = "Synty/Sidekick Character Tool";
|
||||||
@@ -168,19 +168,61 @@ namespace Synty.SidekickCharacters
|
|||||||
|
|
||||||
private void SaveCurrentInstalledVersion(string version)
|
private void SaveCurrentInstalledVersion(string version)
|
||||||
{
|
{
|
||||||
File.WriteAllText(_VERSION_FILE, version);
|
string versionFilePath = GetVersionFilePath();
|
||||||
|
if (string.IsNullOrEmpty(versionFilePath))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Unable to resolve Sidekick version file path.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(versionFilePath, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string LoadCurrentInstalledVersion()
|
private string LoadCurrentInstalledVersion()
|
||||||
{
|
{
|
||||||
if (File.Exists(_VERSION_FILE))
|
string versionFilePath = GetVersionFilePath();
|
||||||
|
if (string.IsNullOrEmpty(versionFilePath))
|
||||||
{
|
{
|
||||||
return File.ReadAllText(_VERSION_FILE);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(versionFilePath))
|
||||||
|
{
|
||||||
|
return File.ReadAllText(versionFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetVersionFilePath()
|
||||||
|
{
|
||||||
|
MonoScript currentScript = MonoScript.FromScriptableObject(this);
|
||||||
|
if (currentScript == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string scriptPath = AssetDatabase.GetAssetPath(currentScript);
|
||||||
|
if (string.IsNullOrEmpty(scriptPath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string utilityDirectory = Path.GetDirectoryName(scriptPath);
|
||||||
|
if (string.IsNullOrEmpty(utilityDirectory))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string editorDirectory = Path.GetDirectoryName(utilityDirectory);
|
||||||
|
if (string.IsNullOrEmpty(editorDirectory))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Path.GetFullPath(Path.Combine(editorDirectory, _VERSION_FILE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
private void DownloadLatestDBVersion()
|
private void DownloadLatestDBVersion()
|
||||||
{
|
{
|
||||||
WebClient client = new WebClient();
|
WebClient client = new WebClient();
|
||||||
|
|||||||
@@ -230,6 +230,42 @@ namespace Synty.SidekickCharacters.API
|
|||||||
await runtime.PopulatePresetLibrary();
|
await runtime.PopulatePresetLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<string> GetSidekickPartFiles()
|
||||||
|
{
|
||||||
|
string packageRootPath = DatabaseManager.GetPackageRootAbsolutePath();
|
||||||
|
if (!string.IsNullOrEmpty(packageRootPath))
|
||||||
|
{
|
||||||
|
string meshesRootPath = Path.Combine(packageRootPath, "Resources", "Meshes");
|
||||||
|
if (Directory.Exists(meshesRootPath))
|
||||||
|
{
|
||||||
|
return Directory
|
||||||
|
.GetFiles(meshesRootPath, "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories)
|
||||||
|
.Select(ToAssetPath)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToAssetPath(string fullPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(fullPath))
|
||||||
|
{
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string normalizedFullPath = fullPath.Replace('\\', '/');
|
||||||
|
string normalizedAssetsPath = Application.dataPath.Replace('\\', '/');
|
||||||
|
|
||||||
|
if (!normalizedFullPath.StartsWith(normalizedAssetsPath, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return normalizedFullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Assets" + normalizedFullPath.Substring(normalizedAssetsPath.Length);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Takes all the parts selected in the window, and combines them into a single model in the scene.
|
/// Takes all the parts selected in the window, and combines them into a single model in the scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -512,7 +548,7 @@ namespace Synty.SidekickCharacters.API
|
|||||||
_partOutfitToggleMap = new Dictionary<string, bool>();
|
_partOutfitToggleMap = new Dictionary<string, bool>();
|
||||||
_partCount = 0;
|
_partCount = 0;
|
||||||
|
|
||||||
List<string> files = Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
|
List<string> files = GetSidekickPartFiles();
|
||||||
|
|
||||||
foreach (CharacterPartType partType in Enum.GetValues(typeof(CharacterPartType)))
|
foreach (CharacterPartType partType in Enum.GetValues(typeof(CharacterPartType)))
|
||||||
{
|
{
|
||||||
@@ -610,7 +646,7 @@ namespace Synty.SidekickCharacters.API
|
|||||||
_speciesDictionary = new Dictionary<string, SidekickSpecies>();
|
_speciesDictionary = new Dictionary<string, SidekickSpecies>();
|
||||||
_partCount = 0;
|
_partCount = 0;
|
||||||
|
|
||||||
List<string> files = Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
|
List<string> files = GetSidekickPartFiles();
|
||||||
Dictionary<string, string> filesOnDisk = new Dictionary<string, string>();
|
Dictionary<string, string> filesOnDisk = new Dictionary<string, string>();
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -154,6 +154,18 @@ namespace Synty.SidekickCharacters.Database.DTO
|
|||||||
/// <returns>A color set with all DTO class properties set</returns>
|
/// <returns>A color set with all DTO class properties set</returns>
|
||||||
private static void Decorate(DatabaseManager dbManager, SidekickColorSet set)
|
private static void Decorate(DatabaseManager dbManager, SidekickColorSet set)
|
||||||
{
|
{
|
||||||
|
if (set == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set.SourceColorPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceColorPath);
|
||||||
|
set.SourceMetallicPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceMetallicPath);
|
||||||
|
set.SourceSmoothnessPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceSmoothnessPath);
|
||||||
|
set.SourceReflectionPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceReflectionPath);
|
||||||
|
set.SourceEmissionPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceEmissionPath);
|
||||||
|
set.SourceOpacityPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceOpacityPath);
|
||||||
|
|
||||||
if (set.Species == null && set.PtrSpecies >= 0)
|
if (set.Species == null && set.PtrSpecies >= 0)
|
||||||
{
|
{
|
||||||
set.Species = SidekickSpecies.GetByID(dbManager, set.PtrSpecies);
|
set.Species = SidekickSpecies.GetByID(dbManager, set.PtrSpecies);
|
||||||
|
|||||||
@@ -222,6 +222,8 @@ namespace Synty.SidekickCharacters.Database.DTO
|
|||||||
{
|
{
|
||||||
if (part != null)
|
if (part != null)
|
||||||
{
|
{
|
||||||
|
part.Location = DatabaseManager.NormalizeLegacyAssetPath(part.Location);
|
||||||
|
|
||||||
if (part.Species == null && part.PtrSpecies >= 0)
|
if (part.Species == null && part.PtrSpecies >= 0)
|
||||||
{
|
{
|
||||||
part.Species = SidekickSpecies.GetByID(dbManager, part.PtrSpecies);
|
part.Species = SidekickSpecies.GetByID(dbManager, part.PtrSpecies);
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
using Synty.SidekickCharacters.Database.DTO;
|
using Synty.SidekickCharacters.Database.DTO;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Synty.SidekickCharacters.Database
|
namespace Synty.SidekickCharacters.Database
|
||||||
{
|
{
|
||||||
@@ -21,11 +23,18 @@ namespace Synty.SidekickCharacters.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DatabaseManager
|
public class DatabaseManager
|
||||||
{
|
{
|
||||||
private static readonly string _DATABASE_PATH = "Assets/Synty/SidekickCharacters/Database/Side_Kick_Data.db";
|
private const string _DATABASE_FILE_NAME = "Side_Kick_Data.db";
|
||||||
|
private const string _LEGACY_PACKAGE_ROOT = "Assets/Synty/SidekickCharacters";
|
||||||
|
private const string _LEGACY_TOOLS_PACKAGE_ROOT = "Assets/Synty/Tools/SidekickCharacters";
|
||||||
|
private const string _WORKING_DATABASE_DIRECTORY = "SidekickCharacters";
|
||||||
private readonly string _CURRENT_VERSION = "1.0.2";
|
private readonly string _CURRENT_VERSION = "1.0.2";
|
||||||
|
|
||||||
private static SQLiteConnection _connection;
|
private static SQLiteConnection _connection;
|
||||||
private static int _connectionHash;
|
private static int _connectionHash;
|
||||||
|
private static string _databasePath;
|
||||||
|
private static string _seedDatabasePath;
|
||||||
|
private static string _packageRootAbsolutePath;
|
||||||
|
private static string _packageRootAssetPath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the DB connection with the given connection details.
|
/// Gets the DB connection with the given connection details.
|
||||||
@@ -39,7 +48,13 @@ namespace Synty.SidekickCharacters.Database
|
|||||||
{
|
{
|
||||||
if (_connection == null)
|
if (_connection == null)
|
||||||
{
|
{
|
||||||
_connection = new SQLiteConnection(_DATABASE_PATH, true);
|
string databasePath = GetDatabasePath();
|
||||||
|
if (string.IsNullOrEmpty(databasePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("Unable to locate Sidekick database file in this Unity project.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_connection = new SQLiteConnection(databasePath, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -100,12 +115,12 @@ namespace Synty.SidekickCharacters.Database
|
|||||||
{
|
{
|
||||||
Species = new SidekickSpecies { ID = -1, Name = "None" },
|
Species = new SidekickSpecies { ID = -1, Name = "None" },
|
||||||
Name = "Default",
|
Name = "Default",
|
||||||
SourceColorPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_ColorMap.png",
|
SourceColorPath = GetPackageAssetPath("Resources", "Textures", "T_ColorMap.png"),
|
||||||
SourceMetallicPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_MetallicMap.png",
|
SourceMetallicPath = GetPackageAssetPath("Resources", "Textures", "T_MetallicMap.png"),
|
||||||
SourceSmoothnessPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_SmoothnessMap.png",
|
SourceSmoothnessPath = GetPackageAssetPath("Resources", "Textures", "T_SmoothnessMap.png"),
|
||||||
SourceReflectionPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_ReflectionMap.png",
|
SourceReflectionPath = GetPackageAssetPath("Resources", "Textures", "T_ReflectionMap.png"),
|
||||||
SourceEmissionPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_EmissionMap.png",
|
SourceEmissionPath = GetPackageAssetPath("Resources", "Textures", "T_EmissionMap.png"),
|
||||||
SourceOpacityPath = "Assets/Synty/Tools/SidekickCharacters/Resources/Textures/T_OpacityMap.png",
|
SourceOpacityPath = GetPackageAssetPath("Resources", "Textures", "T_OpacityMap.png"),
|
||||||
};
|
};
|
||||||
|
|
||||||
newSet.Save(this);
|
newSet.Save(this);
|
||||||
@@ -206,5 +221,216 @@ namespace Synty.SidekickCharacters.Database
|
|||||||
{
|
{
|
||||||
return new Version(GetCurrentDbConnection()?.Table<SidekickDBVersion>().FirstOrDefault().SemanticVersion ?? "0.0.1ea");
|
return new Version(GetCurrentDbConnection()?.Table<SidekickDBVersion>().FirstOrDefault().SemanticVersion ?? "0.0.1ea");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the absolute filesystem path to the Sidekick database file.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The absolute path to the DB file, if found.</returns>
|
||||||
|
public static string GetDatabasePath()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_databasePath) && File.Exists(_databasePath))
|
||||||
|
{
|
||||||
|
return _databasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string seedDatabasePath = GetSeedDatabasePath();
|
||||||
|
if (string.IsNullOrEmpty(seedDatabasePath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string projectRoot = Directory.GetParent(Application.dataPath)?.FullName;
|
||||||
|
if (string.IsNullOrEmpty(projectRoot))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string workingDirectory = Path.Combine(projectRoot, "Library", _WORKING_DATABASE_DIRECTORY);
|
||||||
|
Directory.CreateDirectory(workingDirectory);
|
||||||
|
|
||||||
|
_databasePath = Path.Combine(workingDirectory, _DATABASE_FILE_NAME);
|
||||||
|
if (!File.Exists(_databasePath))
|
||||||
|
{
|
||||||
|
File.Copy(seedDatabasePath, _databasePath, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_databasePath = Path.GetFullPath(_databasePath);
|
||||||
|
CleanupLegacyDatabaseArtifacts(seedDatabasePath);
|
||||||
|
return _databasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the absolute filesystem path to the Sidekick package root.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The absolute path to the package root, if found.</returns>
|
||||||
|
public static string GetPackageRootAbsolutePath()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_packageRootAbsolutePath) && Directory.Exists(_packageRootAbsolutePath))
|
||||||
|
{
|
||||||
|
return _packageRootAbsolutePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string seedDatabasePath = GetSeedDatabasePath();
|
||||||
|
if (string.IsNullOrEmpty(seedDatabasePath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string databaseDirectory = Path.GetDirectoryName(seedDatabasePath);
|
||||||
|
if (string.IsNullOrEmpty(databaseDirectory))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_packageRootAbsolutePath = Path.GetDirectoryName(databaseDirectory);
|
||||||
|
if (!string.IsNullOrEmpty(_packageRootAbsolutePath))
|
||||||
|
{
|
||||||
|
_packageRootAbsolutePath = Path.GetFullPath(_packageRootAbsolutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _packageRootAbsolutePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the project-relative asset path to the Sidekick package root.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The asset path to the package root, if found.</returns>
|
||||||
|
public static string GetPackageRootAssetPath()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_packageRootAssetPath))
|
||||||
|
{
|
||||||
|
return _packageRootAssetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string packageRootAbsolutePath = GetPackageRootAbsolutePath();
|
||||||
|
if (string.IsNullOrEmpty(packageRootAbsolutePath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_packageRootAssetPath = ToAssetPath(packageRootAbsolutePath);
|
||||||
|
return _packageRootAssetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a project-relative asset path under the Sidekick package root.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativeSegments">Path segments under the package root.</param>
|
||||||
|
/// <returns>The combined asset path, if the package root could be found.</returns>
|
||||||
|
public static string GetPackageAssetPath(params string[] relativeSegments)
|
||||||
|
{
|
||||||
|
string packageRootAssetPath = GetPackageRootAssetPath();
|
||||||
|
if (string.IsNullOrEmpty(packageRootAssetPath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string combinedPath = packageRootAssetPath;
|
||||||
|
foreach (string segment in relativeSegments)
|
||||||
|
{
|
||||||
|
combinedPath = Path.Combine(combinedPath, segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NormalizePathSeparators(combinedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normalizes legacy Sidekick asset paths so moved packages still load correctly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetPath">The asset path to normalize.</param>
|
||||||
|
/// <returns>The remapped path if it pointed at an old root; otherwise the original path.</returns>
|
||||||
|
public static string NormalizeLegacyAssetPath(string assetPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(assetPath))
|
||||||
|
{
|
||||||
|
return assetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string normalizedPath = NormalizePathSeparators(assetPath);
|
||||||
|
string packageRootAssetPath = GetPackageRootAssetPath();
|
||||||
|
if (string.IsNullOrEmpty(packageRootAssetPath))
|
||||||
|
{
|
||||||
|
return normalizedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedPath.StartsWith(_LEGACY_TOOLS_PACKAGE_ROOT, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return packageRootAssetPath + normalizedPath.Substring(_LEGACY_TOOLS_PACKAGE_ROOT.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedPath.StartsWith(_LEGACY_PACKAGE_ROOT, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return packageRootAssetPath + normalizedPath.Substring(_LEGACY_PACKAGE_ROOT.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToAssetPath(string fullPath)
|
||||||
|
{
|
||||||
|
string normalizedFullPath = NormalizePathSeparators(Path.GetFullPath(fullPath));
|
||||||
|
string normalizedAssetsPath = NormalizePathSeparators(Path.GetFullPath(Application.dataPath));
|
||||||
|
|
||||||
|
if (!normalizedFullPath.StartsWith(normalizedAssetsPath, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return normalizedFullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Assets" + normalizedFullPath.Substring(normalizedAssetsPath.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizePathSeparators(string path)
|
||||||
|
{
|
||||||
|
return path?.Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetSeedDatabasePath()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_seedDatabasePath) && File.Exists(_seedDatabasePath))
|
||||||
|
{
|
||||||
|
return _seedDatabasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] databaseFiles = Directory.GetFiles(Application.dataPath, _DATABASE_FILE_NAME, SearchOption.AllDirectories);
|
||||||
|
_seedDatabasePath = databaseFiles
|
||||||
|
.OrderBy(path => path.Contains($"{Path.DirectorySeparatorChar}SidekickCharacters{Path.DirectorySeparatorChar}Database{Path.DirectorySeparatorChar}") ? 0 : 1)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_seedDatabasePath))
|
||||||
|
{
|
||||||
|
_seedDatabasePath = Path.GetFullPath(_seedDatabasePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _seedDatabasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CleanupLegacyDatabaseArtifacts(string seedDatabasePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(seedDatabasePath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteIfExists(seedDatabasePath + "-journal");
|
||||||
|
DeleteIfExists(seedDatabasePath + "-journal.meta");
|
||||||
|
DeleteIfExists(seedDatabasePath + "-wal");
|
||||||
|
DeleteIfExists(seedDatabasePath + "-wal.meta");
|
||||||
|
DeleteIfExists(seedDatabasePath + "-shm");
|
||||||
|
DeleteIfExists(seedDatabasePath + "-shm.meta");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeleteIfExists(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user