186 lines
5.9 KiB
C#
186 lines
5.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Newtonsoft.Json;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.EditorTools
|
|
{
|
|
[Serializable]
|
|
public class TimelineNameCacheEntry
|
|
{
|
|
public string guid;
|
|
public string assetPath;
|
|
public string fileHash;
|
|
public string lastModified;
|
|
public string timelineName;
|
|
public string gameObjectPath;
|
|
public bool isInScene;
|
|
public int lineNumber;
|
|
}
|
|
|
|
[Serializable]
|
|
public class TimelineNameCache
|
|
{
|
|
public const int CurrentVersion = 1;
|
|
|
|
public int version = CurrentVersion;
|
|
public string lastFullScanTime;
|
|
public List<TimelineNameCacheEntry> entries = new List<TimelineNameCacheEntry>();
|
|
|
|
private static readonly string CacheFolderRelativePath = "Assets/Editor/TimelineNameCollector/Cache";
|
|
private static readonly string CacheFileName = "timeline_name_cache.json";
|
|
|
|
public static string CacheFolderFullPath =>
|
|
Path.Combine(Application.dataPath, "Editor/TimelineNameCollector/Cache");
|
|
|
|
public static string CacheFileFullPath =>
|
|
Path.Combine(CacheFolderFullPath, CacheFileName);
|
|
|
|
public static TimelineNameCache Load()
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(CacheFileFullPath))
|
|
{
|
|
return new TimelineNameCache
|
|
{
|
|
version = CurrentVersion,
|
|
lastFullScanTime = null,
|
|
entries = new List<TimelineNameCacheEntry>()
|
|
};
|
|
}
|
|
|
|
var json = File.ReadAllText(CacheFileFullPath, Encoding.UTF8);
|
|
if (string.IsNullOrEmpty(json))
|
|
{
|
|
return new TimelineNameCache
|
|
{
|
|
version = CurrentVersion,
|
|
lastFullScanTime = null,
|
|
entries = new List<TimelineNameCacheEntry>()
|
|
};
|
|
}
|
|
|
|
var cache = JsonConvert.DeserializeObject<TimelineNameCache>(json);
|
|
if (cache == null)
|
|
{
|
|
cache = new TimelineNameCache();
|
|
}
|
|
|
|
if (cache.version != CurrentVersion)
|
|
{
|
|
cache.version = CurrentVersion;
|
|
cache.lastFullScanTime = null;
|
|
cache.entries = cache.entries ?? new List<TimelineNameCacheEntry>();
|
|
}
|
|
|
|
return cache;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"[TimelineNameCache] Failed to load cache: {e}");
|
|
return new TimelineNameCache
|
|
{
|
|
version = CurrentVersion,
|
|
lastFullScanTime = null,
|
|
entries = new List<TimelineNameCacheEntry>()
|
|
};
|
|
}
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
try
|
|
{
|
|
if (!Directory.Exists(CacheFolderFullPath))
|
|
{
|
|
Directory.CreateDirectory(CacheFolderFullPath);
|
|
}
|
|
|
|
entries ??= new List<TimelineNameCacheEntry>();
|
|
|
|
var settings = new JsonSerializerSettings
|
|
{
|
|
Formatting = Formatting.Indented,
|
|
StringEscapeHandling = StringEscapeHandling.Default
|
|
};
|
|
var json = JsonConvert.SerializeObject(this, settings);
|
|
File.WriteAllText(CacheFileFullPath, json, Encoding.UTF8);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"[TimelineNameCache] Failed to save cache: {e}");
|
|
}
|
|
}
|
|
|
|
public void SetLastFullScanNow()
|
|
{
|
|
lastFullScanTime = DateTime.UtcNow.ToString("o");
|
|
}
|
|
|
|
public static string ComputeFileHash(string fullPath)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(fullPath))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
using (var stream = File.OpenRead(fullPath))
|
|
using (var md5 = MD5.Create())
|
|
{
|
|
var hash = md5.ComputeHash(stream);
|
|
var sb = new StringBuilder(hash.Length * 2);
|
|
foreach (var b in hash)
|
|
{
|
|
sb.Append(b.ToString("x2"));
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"[TimelineNameCache] Failed to compute file hash for '{fullPath}': {e}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static string GetAssetFullPath(string assetPath)
|
|
{
|
|
if (string.IsNullOrEmpty(assetPath))
|
|
return null;
|
|
|
|
if (!assetPath.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase) &&
|
|
!assetPath.Equals("Assets", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var relative = assetPath.Substring("Assets".Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
return Path.Combine(Application.dataPath, relative);
|
|
}
|
|
|
|
public void RemoveEntriesForAsset(string assetPath)
|
|
{
|
|
if (entries == null || string.IsNullOrEmpty(assetPath)) return;
|
|
entries.RemoveAll(e => e != null && e.assetPath == assetPath);
|
|
}
|
|
|
|
public void CleanupDeletedAssets()
|
|
{
|
|
if (entries == null) return;
|
|
entries.RemoveAll(e =>
|
|
{
|
|
if (e == null || string.IsNullOrEmpty(e.assetPath)) return true;
|
|
return AssetDatabase.LoadMainAssetAtPath(e.assetPath) == null;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|