using LightningDB; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace AssetDependencyGraph { public sealed class UnityLmdb { private Dictionary guid2Path = new(); private Dictionary path2Guid = new(); private static readonly string unityPath; private static readonly string projPath; static UnityLmdb() { var args = Environment.GetCommandLineArgs(); unityPath = Path.GetDirectoryName(args[0]); for (int i = 0; i < args.Length; i++) { if (args[i].ToLowerInvariant() == "-projectpath") { projPath = args[i + 1]; break; } } } public static byte[] Guid2LmdbKey(string guid) { var inputByteArray = new byte[guid.Length / 2]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < guid.Length; i += 2) { sb.Append(guid[i + 1]); sb.Append(guid[i]); } guid = sb.ToString(); for (var x = 0; x < inputByteArray.Length; x++) { inputByteArray[x] = (byte)Convert.ToInt32(guid.Substring(x * 2, 2), 16); } return inputByteArray; } public static string LmdbKey2Guid(byte[] bytes) { StringBuilder ret = new StringBuilder(); for (var i = 0; i < bytes.Length; i++) { ret.AppendFormat("{0:x2}", bytes[i]); if (ret.Length == 32) { break; } } for (int i = 0; i < ret.Length; i += 2) { var c = ret[i]; ret[i] = ret[i + 1]; ret[i + 1] = c; } var hex = ret.ToString(); return hex; } public void ResolveGuidPath() { var sourceDbPath = Path.Combine(projPath, "Library", "SourceAssetDB"); var dbPath = Path.Combine(projPath, "Library", "SourceAssetDB1"); File.Copy(sourceDbPath, dbPath, true); using var env = new LightningEnvironment(dbPath, configuration: new() { MaxDatabases = 64, MaxReaders = 64, }); env.Open(EnvironmentOpenFlags.NoSubDir | EnvironmentOpenFlags.ReadOnly); using var tx = env.BeginTransaction(TransactionBeginFlags.ReadOnly); using (var db = tx.OpenDatabase("GuidToPath", closeOnDispose: true)) using (var cursor = tx.CreateCursor(db)) { foreach (var item in cursor.AsEnumerable()) { guid2Path[LmdbKey2Guid(item.Item1.AsSpan().ToArray())] = Encoding.UTF8.GetString(item.Item2.AsSpan()).ToLowerInvariant().Trim(); } } using (var db = tx.OpenDatabase("PathToGuid", closeOnDispose: true)) using (var cursor = tx.CreateCursor(db)) { foreach (var item in cursor.AsEnumerable()) { path2Guid[Encoding.UTF8.GetString(item.Item1.AsSpan()).ToLowerInvariant().Trim()] = LmdbKey2Guid(item.Item2.AsSpan().ToArray()); } } } public string GetGuidByPath(string path) { if (path2Guid.ContainsKey(path)) { return path2Guid[path]; } else { return null; } } public string GetPathByGuid(string guid) { if (guid2Path.ContainsKey(guid)) { return guid2Path[guid]; } else { return null; } } } }