using UnityEngine; using UnityEditor; using System.IO; using System.Collections.Generic; using IOCompression = System.IO.Compression; namespace EFSDK { public class AndroidResAarBuilder { private static readonly string ResDir = "Assets/StreamingAssets/Android/res"; private static readonly string OutputDir = "Assets/Plugins/Android"; private static readonly string TempDir = "Temp/AndroidResAar"; private static readonly string EFSdk_FILE = "Assets/EFSDK/EFSdk.cs"; [MenuItem("EFSDK/Build Android Res AAR")] public static void BuildAAR() { if (!Directory.Exists(ResDir)) { Debug.LogError($"Res folder not found: {ResDir}"); return; } // 清理临时目录 if (Directory.Exists(TempDir)) Directory.Delete(TempDir, true); Directory.CreateDirectory(TempDir); // 复制资源并重命名 CopyAndRenameFiles(ResDir, TempDir, out Dictionary mapping); string manifestPath = Path.Combine(TempDir, "AndroidManifest.xml"); File.WriteAllText(manifestPath, @" "); // 打包 AAR string aarPath = Path.Combine(OutputDir, "efsdk_res.aar"); if (!Directory.Exists(OutputDir)) Directory.CreateDirectory(OutputDir); if (File.Exists(aarPath)) File.Delete(aarPath); IOCompression.ZipFile.CreateFromDirectory(TempDir, aarPath, IOCompression.CompressionLevel.Optimal, false); Debug.Log($"✅ AAR built: {aarPath}"); // 生成压缩 JSON (key 只保留文件名) Dictionary simpleMapping = new Dictionary(); foreach (var kv in mapping) { string fileName = Path.GetFileName(kv.Key); simpleMapping[fileName] = kv.Value; } string mappingJson = GenerateMappingJson(mapping); // 更新 mappingInfo UpdateMappingInEFSdk_LineByLine(mappingJson); // 映射文件 string mappingPath = Path.Combine(TempDir, "res_mapping.json"); File.WriteAllText(mappingPath, mappingJson); // 清理临时目录 Directory.Delete(TempDir, true); AssetDatabase.Refresh(); } private static void CopyAndRenameFiles(string srcDir, string dstDir, out Dictionary mapping) { mapping = new Dictionary(); foreach (var filePath in Directory.GetFiles(srcDir, "*", SearchOption.AllDirectories)) { if (filePath.EndsWith(".meta")) continue; string relativePath = filePath.Substring(srcDir.Length + 1).Replace("\\", "/"); string newName = GenerateRandomAndroidName(Path.GetExtension(filePath)); mapping[Path.GetFileName(filePath)] = newName; string dstPath = Path.Combine(dstDir, newName); string dstFolder = Path.GetDirectoryName(dstPath); if (!Directory.Exists(dstFolder)) Directory.CreateDirectory(dstFolder); File.Copy(filePath, dstPath); } foreach (var dir in Directory.GetDirectories(srcDir, "*", SearchOption.AllDirectories)) { string relativeDir = dir.Substring(srcDir.Length + 1); string dstSubDir = Path.Combine(dstDir, relativeDir); if (!Directory.Exists(dstSubDir)) Directory.CreateDirectory(dstSubDir); } Debug.Log("✅ Files copied and renamed"); } private static string GenerateMappingJson(Dictionary mapping) { var items = new List(); foreach (var kv in mapping) { items.Add(new MappingItem { key = kv.Key, value = kv.Value }); } MappingListWrapper wrapper = new MappingListWrapper { items = items }; return JsonUtility.ToJson(wrapper, false); } [System.Serializable] private class MappingItem { public string key; public string value; } [System.Serializable] private class MappingListWrapper { public List items; } private static string GenerateRandomAndroidName(string ext) { int len = UnityEngine.Random.Range(6, 12); string chars = "abcdefghijklmnopqrstuvwxyz0123456789"; string name = ""; for (int i = 0; i < len; i++) { name += chars[UnityEngine.Random.Range(0, chars.Length)]; } if (!char.IsLetter(name[0])) name = "a" + name.Substring(1); return name + ext; } private static void UpdateMappingInEFSdk_LineByLine(string mappingJson) { if (!File.Exists(EFSdk_FILE)) { Debug.LogError($"EFSdk.cs not found: {EFSdk_FILE}"); return; } string[] lines = File.ReadAllLines(EFSdk_FILE); bool updated = false; for (int i = 0; i < lines.Length; i++) { if (lines[i].Contains("mappingInfo")) { lines[i] = $" private static string mappingInfo = @\"{mappingJson.Replace("\"", "\"\"")}\";"; updated = true; break; // 找到第一行就替换,防止重复 } } if (!updated) { // 如果没有找到 mappingInfo 行,则在 _mEfSdk 后插入 for (int i = 0; i < lines.Length; i++) { if (lines[i].Contains("private static EFSdk _mEfSdk")) { lines[i] += $"\n private static string mappingInfo = @\"{mappingJson.Replace("\"", "\"\"")}\";"; updated = true; break; } } } File.WriteAllLines(EFSdk_FILE, lines); Debug.Log("✅ mappingInfo updated in EFSdk.cs (line-by-line)"); } } }