using XGame.Framework.Asset.Addressable;
using XGame.Framework.Asset.Addressable.Data;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace XGame.Editor.Asset
{
public static partial class AddressableHelper
{
private static string GetAssetManifestPath(AddressableClassify classify)
{
switch (classify)
{
case AddressableClassify.BuiltIn:
return PathDefine.BuiltInAssetManifestPath;
case AddressableClassify.Tests:
return PathDefine.TestAssetsManifestPath;
case AddressableClassify.Backup:
return PathDefine.AddressableBackupManifestPath;
default:
return PathDefine.ProductAssetManifestPath;
}
}
///
/// 加载 AddressableAssetInfoManifest
///
///
public static AddressableInfosSo LoadAssetManifest(AddressableClassify classify = AddressableClassify.Product)
{
var manifest = AssetDatabase.LoadAssetAtPath(GetAssetManifestPath(classify));
//if (manifest != null)
//{
// manifest.Init();
//}
return manifest;
}
internal static AddressableInfosSo LoadOrCreateManifest(AddressableClassify classify = AddressableClassify.Product)
{
var manifestPath = GetAssetManifestPath(classify);
var manifest = AssetDatabase.LoadAssetAtPath(manifestPath);
if (manifest == null)
{
if ((classify == AddressableClassify.BuiltIn && !Directory.Exists(PathDefine.BuiltInResourcesRelative))
|| (classify == AddressableClassify.Tests && !Directory.Exists(PathDefine.TestsToAddressable) && !Directory.Exists(PathDefine.BuiltInResTests)))
{
//文件夹不存在
return manifest;
}
if (!Directory.Exists(PathDefine.ConfigsRelative))
{
Directory.CreateDirectory(PathDefine.ConfigsRelative);
}
if (!Directory.Exists(PathDefine.AddressableDataRelative))
{
Directory.CreateDirectory(PathDefine.AddressableDataRelative);
}
manifest = ScriptableObject.CreateInstance();
AssetDatabase.CreateAsset(manifest, manifestPath);
}
return manifest;
}
public static bool TryApplyAddressableName(AddressableInfosSo manifest, string guid,
string addressableName)
{
if (manifest == null)
{
return false;
}
//待优化
if (IsValidName(addressableName))
{
Debug.LogError($"AddressableName repeat. Please rename it. Name:{addressableName} Path:{AssetDatabase.GUIDToAssetPath(guid)}");
return false;
}
if (manifest.TryApplyAddressableName(guid, addressableName, out var assetInfo))
{
var manifestPath = AssetDatabase.GetAssetPath(manifest);
if (PathDefine.ProductAssetManifestPath.Equals(manifestPath) || PathDefine.BuiltInAssetManifestPath.Equals(manifestPath))
{
ApplyBackupAssetInfo(assetInfo);
}
return true;
}
return false;
}
public static bool TryRemoveAssetByGUID(AddressableInfosSo manifest, string guid)
{
if (manifest != null && manifest.TryRemoveAssetByGUID(guid))
{
var manifestPath = AssetDatabase.GetAssetPath(manifest);
if (PathDefine.ProductAssetManifestPath.Equals(manifestPath) || PathDefine.BuiltInAssetManifestPath.Equals(manifestPath))
{ //删除备份
var backup = LoadAssetManifest(AddressableClassify.Backup);
backup?.TryRemoveAssetByGUID(guid);
}
return true;
}
return false;
}
public static bool RemoveAllInvalidAssets(AddressableInfosSo manifest)
{
if (manifest != null && manifest.RemoveAllInvalidAssets())
{
var manifestPath = AssetDatabase.GetAssetPath(manifest);
if (PathDefine.ProductAssetManifestPath.Equals(manifestPath))
{
var backup = LoadAssetManifest(AddressableClassify.Backup);
backup?.RemoveAllInvalidAssets();
}
return true;
}
return false;
}
private static void ApplyBackupAssetInfo(AssetInfo assetInfo)
{
var backup = LoadAssetManifest(AddressableClassify.Backup);
if (backup != null)
{
var isNameDefault = IsDefaultAddressableName(assetInfo.addressableName, assetInfo.assetGUID);
if (isNameDefault || !IsValidPath(assetInfo.GetAssetPath()))
{ //默认名字或者无效资源
backup.TryRemoveAssetByGUID(assetInfo.assetGUID);
}
else
{
var assetInfos = backup.assetInfos.ToList();
var index = assetInfos.FindIndex((info => info.assetGUID.Equals(assetInfo.assetGUID)));
if (index >= 0)
{
assetInfos[index] = assetInfo;
}
else
{
assetInfos.Add(assetInfo);
}
backup.SetAssetInfos(assetInfos.ToArray());
}
}
}
///
/// 收集所有自定义的AddressableName
///
private static void CollectCustomAddressableNames()
{
var backup = LoadAssetManifest(AddressableClassify.Backup);
if (backup != null)
{
var assetInfos = backup.GetAssetInfos();
assetInfos.Clear();
AddressableClassify[] operations = { AddressableClassify.BuiltIn, AddressableClassify.Product };
for (int i = 0; i < operations.Length; i++)
{
var manifest = LoadAssetManifest(operations[i]);
if (manifest != null && manifest.assetInfos != null)
{
foreach (var assetInfo in manifest.assetInfos)
{
if (IsValidPath(assetInfo.GetAssetPath()) && !IsDefaultAddressableName(assetInfo.addressableName, assetInfo.assetGUID))
{ //有效资源并且不是默认名字
assetInfos.Add(assetInfo);
}
}
}
}
backup.SetAssetInfos(assetInfos.ToArray());
}
}
internal static bool IsDefaultAddressableName(string addressableName, string guid, System.Func isContantFileName = null)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty(addressableName) || string.IsNullOrEmpty(assetPath))
{
return false;
}
var fileName = GetFileNameIncludeI18n(assetPath);
if (addressableName.Equals(fileName))
{
return true;
}
if (isContantFileName != null && isContantFileName.Invoke(fileName) == false)
{
//addressable配置里没有名字为fileName的配置
return false;
}
var ext = Path.GetExtension(assetPath);
if (addressableName.Equals(($"{fileName}{ext.Replace('.', '_')}").ToLower()))
{
return true;
}
if (addressableName.Equals(($"{fileName}_{guid.Substring(0, 8)}").ToLower()))
{
return true;
}
if (addressableName.Equals(($"{fileName}_{guid}").ToLower()))
{
return true;
}
return false;
}
}
}