162 lines
6.4 KiB
C#
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)");
|
|
}
|
|
}
|
|
} |