SDK_UnityMoney/Assets/EFSDK/Editor/AndroidResAarBuilder.cs

162 lines
6.4 KiB
C#

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<string, string> mapping);
string manifestPath = Path.Combine(TempDir, "AndroidManifest.xml");
File.WriteAllText(manifestPath,
@"<manifest xmlns:android=""http://schemas.android.com/apk/res/android""
package=""com.unity.reswrapper"">
<application/>
</manifest>");
// 打包 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<string, string> simpleMapping = new Dictionary<string, string>();
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<string, string> mapping)
{
mapping = new Dictionary<string, string>();
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<string, string> mapping)
{
var items = new List<MappingItem>();
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<MappingItem> 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)");
}
}
}