c1_unity/Assets/Editor/BFBuildProjectTools/BuildProjectTools.cs
2023-04-03 11:04:31 +08:00

329 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}