329 lines
12 KiB
C#
329 lines
12 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using BFEditor.Resource;
|
||
using BF;
|
||
|
||
namespace BFEditor.Build
|
||
{
|
||
public static class BuildProjectTools
|
||
{
|
||
static string AssetBundleITPath = Application.dataPath + "/../Build/output/{0}";
|
||
static string AssetBundleCachePath = Application.dataPath + "/../HistoryAssetBundles";
|
||
|
||
static BuildProjectTools()
|
||
{
|
||
BuildAndroidUtils.EnsureJavaHome();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 提供给neo出包接口
|
||
/// </summary>
|
||
public static void BuildBFPlayer()
|
||
{
|
||
var dict = BFEditorUtils.GetCommandLineArgs();
|
||
if (dict.TryGetValue("data", out string dataStr))
|
||
{
|
||
Debug.Log("BuildBFPlayer " + dataStr);
|
||
var json = "{\"infos\":" + dataStr + "}";
|
||
var buildInfoCollection = JsonUtility.FromJson<BuildInfoCollection>(json);
|
||
if (!BuildBFPlayer(buildInfoCollection.GetFirstInfo()))
|
||
{
|
||
throw new Exception();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
throw new Exception();
|
||
}
|
||
}
|
||
|
||
public static bool BuildBFPlayer(BuildInfo buildInfo)
|
||
{
|
||
// assetbundles
|
||
if (!BuildResources(buildInfo, Application.streamingAssetsPath, true))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// 删除不进包的多语言
|
||
// if (!DeleteOverLanguageAb(buildInfo))
|
||
// {
|
||
// return false;
|
||
// }
|
||
|
||
// 打包
|
||
if (!BuildPlayer(buildInfo))
|
||
{
|
||
Debug.LogError("[bferror]buildPlayer失败");
|
||
return false;
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
return true;
|
||
}
|
||
|
||
static bool BuildPlayer(BuildInfo buildInfo)
|
||
{
|
||
Debug.Log("[bfinfo]开始打包, bundleName : " + buildInfo.bundleName + " version : " + buildInfo.version + " mode : " + buildInfo.mode);
|
||
|
||
var watch = new System.Diagnostics.Stopwatch();
|
||
watch.Start();
|
||
|
||
var result = false;
|
||
|
||
if (buildInfo.IsAndroidPlatform() && BuildAndroidUtils.BuildAndroidPlayer(buildInfo))
|
||
{
|
||
result = true;
|
||
}
|
||
|
||
#if UNITY_EDITOR_OSX
|
||
if (buildInfo.IsIOSPlatform() && BuildIOSUtils.BuildIOSPlayer(buildInfo))
|
||
{
|
||
result = true;
|
||
}
|
||
#endif
|
||
|
||
if (result)
|
||
{
|
||
watch.Stop();
|
||
Debug.Log("[bfinfo]打包完成,耗时: " + BFEditorUtils.GetTimeStr(watch.ElapsedMilliseconds));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 提供给neo打热更接口
|
||
/// </summary>
|
||
public static void BuildResources()
|
||
{
|
||
var dict = BFEditorUtils.GetCommandLineArgs();
|
||
if (dict.TryGetValue("data", out string dataStr))
|
||
{
|
||
Debug.Log("BuildResources " + dataStr);
|
||
var json = "{\"infos\":" + dataStr + "}";
|
||
var buildInfoCollection = JsonUtility.FromJson<BuildInfoCollection>(json);
|
||
var bulidInfo = buildInfoCollection.GetFirstInfo();
|
||
var itPath = string.Format(AssetBundleITPath, bulidInfo.mode);
|
||
if (!BuildResources(bulidInfo, itPath, false))
|
||
{
|
||
throw new Exception();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
throw new Exception();
|
||
}
|
||
}
|
||
|
||
public static bool BuildResources(BuildInfo buildInfo, string outputPath, bool needCopyToITPath)
|
||
{
|
||
if (Directory.Exists(outputPath))
|
||
{
|
||
Directory.Delete(outputPath, true);
|
||
}
|
||
|
||
// 首先尝试从缓存获取
|
||
// if (TryGetAbFromCache(buildInfo, outputPath))
|
||
// {
|
||
// // 拷贝资源到it上传路径
|
||
// // if (needCopyToITPath)
|
||
// // {
|
||
// // CopyResToITPath(buildInfo, outputPath);
|
||
// // }
|
||
// return true;
|
||
// }
|
||
|
||
var watch = new System.Diagnostics.Stopwatch();
|
||
watch.Start();
|
||
|
||
// var buildTarget = buildInfo.IsIOSPlatform() ? BuildTarget.iOS : BuildTarget.Android;
|
||
var isRelease = buildInfo.IsReleaseChannel();
|
||
Debug.Log("[bfinfo]开始打包资源, bundleName : " + buildInfo.bundleName + " version : " + buildInfo.version + " mode : " + buildInfo.mode);
|
||
|
||
// // 检查平台
|
||
// if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
|
||
// {
|
||
// Debug.LogError("[bferror]当前没有在对应平台");
|
||
// return false;
|
||
// }
|
||
|
||
// 更新atlas
|
||
MainAtlasTools.UpdateMainAtlas();
|
||
// LanguageAtlasTools.UpdateLanguageAtlas();
|
||
|
||
// 生成tmp字体
|
||
TMPTools.GenFormalFontAsset(false);
|
||
|
||
// 清理fbx默认材质
|
||
MaterialTools.ClearFbxDefaultMaterial();
|
||
|
||
// 清理shader依赖资源
|
||
ShaderDependenciesTools.ClearAllShaderDependencies();
|
||
|
||
// 收集shader变体
|
||
ShaderVariantsTools.GenerateVariantCollection();
|
||
|
||
// ios因为环境问题,先不编译,打版本前提前编译好
|
||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
|
||
{
|
||
// 编译并且加密lua代码
|
||
if (!CompileScriptsUtils.CompileAndEncryptLua(!isRelease))
|
||
{
|
||
Debug.LogError("[bferror]lua代码编译失败");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 设置abName
|
||
AssetBundleUtils.SetAllAssetsBundleName();
|
||
|
||
// 打ab资源
|
||
if (!AssetBundleUtils.BuildAssetBundles(EditorUserBuildSettings.activeBuildTarget, outputPath, isRelease, BuildAssetBundleOptions.ChunkBasedCompression,
|
||
buildInfo.GetLanguageInfo(), buildInfo.version))
|
||
{
|
||
Debug.LogError("[bferror]打ab失败");
|
||
return false;
|
||
}
|
||
|
||
// 检查循环依赖
|
||
if (!ABCycleDependUtils.CheckABCycleDepend(outputPath))
|
||
{
|
||
Debug.LogError("[bferror]打ab失败,ab存在循环依赖");
|
||
return false;
|
||
}
|
||
|
||
// 本地缓存ab
|
||
if (buildInfo.IsReleaseChannel())
|
||
{
|
||
Debug.Log("[bfinfo]正在缓存assetbundles...");
|
||
BFEditorUtils.CopyDirWithIgnore(outputPath, Path.Combine(AssetBundleCachePath, buildInfo.version), new List<string> { ".meta" });
|
||
}
|
||
|
||
// 拷贝资源到it上传路径
|
||
// if (needCopyToITPath)
|
||
// {
|
||
// CopyResToITPath(buildInfo, outputPath);
|
||
// }
|
||
|
||
watch.Stop();
|
||
Debug.Log("[bfinfo]资源打包完成,耗时: " + BFEditorUtils.GetTimeStr(watch.ElapsedMilliseconds));
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 尝试从缓存中获取ab,会进行md5校验
|
||
/// </summary>
|
||
static bool TryGetAbFromCache(BuildInfo buildInfo, string outputPath)
|
||
{
|
||
var cachePath = Path.Combine(AssetBundleCachePath, buildInfo.version);
|
||
if (!Directory.Exists(cachePath))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (CheckCacheAbMd5(cachePath, buildInfo))
|
||
{
|
||
Debug.Log(string.Format("[bfinfo]正在拷贝本地缓存资源 {0} ---> {1}", cachePath, outputPath));
|
||
BFEditorUtils.CopyDirWithIgnore(cachePath, outputPath, new List<string> { ".meta" });
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public static void CopyResToITPath(BuildInfo buildInfo, string outputPath)
|
||
{
|
||
Debug.Log("[bfinfo]正在拷贝assetbundles到运维上传路径...");
|
||
var itPath = string.Format(AssetBundleITPath, buildInfo.mode);
|
||
if (Directory.Exists(itPath))
|
||
{
|
||
Directory.Delete(itPath, true);
|
||
}
|
||
BFEditorUtils.CopyDirWithIgnore(outputPath, itPath, new List<string> { ".meta" });
|
||
}
|
||
|
||
/// <summary>
|
||
/// 校验缓存资源
|
||
/// </summary>
|
||
static bool CheckCacheAbMd5(string abPath, BuildInfo buildInfo)
|
||
{
|
||
Debug.Log("[bfinfo]正在校验缓存资源...");
|
||
|
||
var abccPath = Path.Combine(abPath, "ab_config.bytes");
|
||
if (!File.Exists(abccPath))
|
||
{
|
||
Debug.LogError("[bferror]校验缓存资源失败 ab_config.bytes不存在");
|
||
return false;
|
||
}
|
||
|
||
var bytes = File.ReadAllBytes(abccPath);
|
||
var json = AssetBundleConfigCollection.Decompress(bytes);
|
||
var abcc = AssetBundleConfigCollection.Create(json);
|
||
foreach (var abc in abcc.mainConfigs)
|
||
{
|
||
var path = Path.Combine(abPath, abc.assetBundlePath);
|
||
if (!File.Exists(path))
|
||
{
|
||
Debug.LogError(string.Format("[bferror]校验缓存资源失败 {0} 文件丢失", abc.assetBundlePath));
|
||
return false;
|
||
}
|
||
|
||
var md5 = GameLaunchUtils.GetFileMD5(path);
|
||
if (md5 != abc.md5)
|
||
{
|
||
Debug.LogError(string.Format("[bferror]校验缓存资源失败 {0} 文件md5不一致", abc.assetBundlePath));
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 只有版本号不一样, 则修改abConfig的版本号
|
||
if (abcc.version != buildInfo.version)
|
||
{
|
||
Debug.Log(string.Format("[bfinfo]资源版本号不一样,修改版本号,缓存资源版本{0}, 目标版本{1}", abcc.version, buildInfo.version));
|
||
abcc.version = buildInfo.version;
|
||
var newJson = abcc.ToJson();
|
||
var newBytes = AssetBundleConfigCollection.Compress(newJson);
|
||
File.WriteAllBytes(abccPath, newBytes);
|
||
}
|
||
|
||
Debug.Log("[bfinfo]缓存资源校验完成");
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 剔除冗余的多语言资源
|
||
/// </summary>
|
||
static bool DeleteOverLanguageAb(BuildInfo buildInfo)
|
||
{
|
||
var bundleName = buildInfo.bundleName;
|
||
var languageInfo = BFPlatform.GetLanguageInfo(bundleName);
|
||
if (languageInfo == null)
|
||
{
|
||
Debug.LogError("[bferror]没有对应的多语言info " + bundleName);
|
||
return false;
|
||
}
|
||
|
||
foreach (var languagePath in AssetBundleUtils.languagePathList)
|
||
{
|
||
var languageAbDirPath = Application.streamingAssetsPath + "/" + languagePath;
|
||
var subLanguageDirs = Directory.GetDirectories(languageAbDirPath);
|
||
foreach (var dir in subLanguageDirs)
|
||
{
|
||
var dirInfo = new DirectoryInfo(dir);
|
||
var name = dirInfo.Name;
|
||
if (languageInfo.Contains(name))
|
||
{
|
||
continue;
|
||
}
|
||
Debug.Log("[bfinfo]剔除不进包的多语言资源 " + dirInfo.FullName);
|
||
dirInfo.Delete(true);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|