/// <summary> /// 获取资源包列表 /// </summary> private List <PatchBundle> GetAllPatchBundle(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext) { List <PatchBundle> result = new List <PatchBundle>(1000); List <string> buildinTags = buildParameters.Parameters.GetBuildinTags(); var buildMode = buildParameters.Parameters.BuildMode; bool standardBuild = buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild; foreach (var bundleInfo in buildMapContext.BundleInfos) { var bundleName = bundleInfo.BundleName; string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}"; string hash = GetFileHash(filePath, standardBuild); string crc32 = GetFileCRC(filePath, standardBuild); long size = GetFileSize(filePath, standardBuild); string[] tags = buildMapContext.GetBundleTags(bundleName); bool isEncrypted = encryptionContext.IsEncryptFile(bundleName); bool isBuildin = IsBuildinBundle(tags, buildinTags); bool isRawFile = bundleInfo.IsRawFile; // 附加文件扩展名 if (buildParameters.Parameters.AppendFileExtension) { hash += bundleInfo.GetAppendExtension(); } PatchBundle patchBundle = new PatchBundle(bundleName, hash, crc32, size, tags); patchBundle.SetFlagsValue(isEncrypted, isBuildin, isRawFile); result.Add(patchBundle); } return(result); }
/// <summary> /// 创建补丁清单文件到输出目录 /// </summary> private void CreatePatchManifestFile(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext) { int resourceVersion = buildParameters.Parameters.BuildVersion; // 创建新补丁清单 PatchManifest patchManifest = new PatchManifest(); patchManifest.EnableAddressable = buildParameters.Parameters.EnableAddressable; patchManifest.ResourceVersion = buildParameters.Parameters.BuildVersion; patchManifest.BuildinTags = buildParameters.Parameters.BuildinTags; patchManifest.BundleList = GetAllPatchBundle(buildParameters, buildMapContext, encryptionContext); patchManifest.AssetList = GetAllPatchAsset(buildParameters, buildMapContext, patchManifest); // 创建补丁清单文件 string manifestFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}"; BuildRunner.Log($"创建补丁清单文件:{manifestFilePath}"); PatchManifest.Serialize(manifestFilePath, patchManifest); // 创建补丁清单哈希文件 string manifestHashFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}"; string manifestHash = HashUtility.FileMD5(manifestFilePath); BuildRunner.Log($"创建补丁清单哈希文件:{manifestHashFilePath}"); FileUtility.CreateFile(manifestHashFilePath, manifestHash); // 创建静态版本文件 string staticVersionFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.VersionFileName}"; string staticVersion = resourceVersion.ToString(); BuildRunner.Log($"创建静态版本文件:{staticVersionFilePath}"); FileUtility.CreateFile(staticVersionFilePath, staticVersion); }
/// <summary> /// 获取资源列表 /// </summary> private List <PatchAsset> GetAllPatchAsset(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext, PatchManifest patchManifest) { List <PatchAsset> result = new List <PatchAsset>(1000); foreach (var bundleInfo in buildMapContext.BundleInfos) { var assetInfos = bundleInfo.GetAllPatchAssetInfos(); foreach (var assetInfo in assetInfos) { PatchAsset patchAsset = new PatchAsset(); if (buildParameters.Parameters.EnableAddressable) { patchAsset.Address = assetInfo.Address; } else { patchAsset.Address = string.Empty; } patchAsset.AssetPath = assetInfo.AssetPath; patchAsset.AssetTags = assetInfo.AssetTags.ToArray(); patchAsset.BundleID = GetAssetBundleID(assetInfo.GetBundleName(), patchManifest); patchAsset.DependIDs = GetAssetBundleDependIDs(patchAsset.BundleID, assetInfo, patchManifest); result.Add(patchAsset); } } return(result); }
/// <summary> /// 加密文件 /// </summary> private List <string> EncryptFiles(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext) { var encryptionServices = buildParameters.Parameters.EncryptionServices; // 加密资源列表 List <string> encryptList = new List <string>(); // 如果没有设置加密类 if (encryptionServices == null) { return(encryptList); } int progressValue = 0; foreach (var bundleInfo in buildMapContext.BundleInfos) { if (encryptionServices.Check(bundleInfo.BundleName)) { if (bundleInfo.IsRawFile) { UnityEngine.Debug.LogWarning($"Encryption not support raw file : {bundleInfo.BundleName}"); continue; } encryptList.Add(bundleInfo.BundleName); // 注意:通过判断文件合法性,规避重复加密一个文件 string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleInfo.BundleName}"; byte[] fileData = File.ReadAllBytes(filePath); if (EditorTools.CheckBundleFileValid(fileData)) { byte[] bytes = encryptionServices.Encrypt(fileData); File.WriteAllBytes(filePath, bytes); BuildRunner.Log($"文件加密完成:{filePath}"); } } // 进度条 EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count); } EditorTools.ClearProgressBar(); if (encryptList.Count == 0) { UnityEngine.Debug.LogWarning($"没有发现需要加密的文件!"); } return(encryptList); }
/// <summary> /// 拷贝原生文件 /// </summary> private void CopyRawBundle(BuildMapContext buildMapContext, AssetBundleBuilder.BuildParametersContext buildParametersContext) { foreach (var bundleInfo in buildMapContext.BundleInfos) { if (bundleInfo.IsRawFile) { string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}"; foreach (var buildAsset in bundleInfo.BuildinAssets) { if (buildAsset.IsRawAsset) { EditorTools.CopyFile(buildAsset.AssetPath, dest, true); } } } } }
/// <summary> /// 拷贝补丁文件到补丁包目录 /// </summary> private void CopyPatchFiles(AssetBundleBuilder.BuildParametersContext buildParameters) { int resourceVersion = buildParameters.Parameters.BuildVersion; string packageDirectory = buildParameters.GetPackageDirectory(); BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}"); // 拷贝Report文件 { string reportFileName = YooAssetSettingsData.GetReportFileName(buildParameters.Parameters.BuildVersion); string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{reportFileName}"; string destPath = $"{packageDirectory}/{reportFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝补丁清单文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}"; string destPath = $"{packageDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝补丁清单哈希文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}"; string destPath = $"{packageDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝静态版本文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.VersionFileName}"; string destPath = $"{packageDirectory}/{YooAssetSettings.VersionFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝UnityManifest序列化文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.Setting.UnityManifestFileName}"; string destPath = $"{packageDirectory}/{YooAssetSettingsData.Setting.UnityManifestFileName}"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝UnityManifest文本文件 { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.Setting.UnityManifestFileName}.manifest"; string destPath = $"{packageDirectory}/{YooAssetSettingsData.Setting.UnityManifestFileName}.manifest"; EditorTools.CopyFile(sourcePath, destPath, true); } // 拷贝所有补丁文件 int progressValue = 0; PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory, buildParameters.Parameters.BuildVersion); int patchFileTotalCount = patchManifest.BundleList.Count; foreach (var patchBundle in patchManifest.BundleList) { string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{patchBundle.BundleName}"; string destPath = $"{packageDirectory}/{patchBundle.Hash}"; EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount); } EditorTools.ClearProgressBar(); }
private void CreateReportFile(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext) { PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory, buildParameters.Parameters.BuildVersion); BuildReport buildReport = new BuildReport(); // 概述信息 { buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion; buildReport.Summary.BuildTime = DateTime.Now.ToString(); buildReport.Summary.BuildSeconds = (int)buildParameters.GetBuildingSeconds(); buildReport.Summary.BuildTarget = buildParameters.Parameters.BuildTarget; buildReport.Summary.BuildMode = buildParameters.Parameters.BuildMode; buildReport.Summary.BuildVersion = buildParameters.Parameters.BuildVersion; buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags; buildReport.Summary.EnableAddressable = buildParameters.Parameters.EnableAddressable; buildReport.Summary.AppendFileExtension = buildParameters.Parameters.AppendFileExtension; buildReport.Summary.CopyBuildinTagFiles = buildParameters.Parameters.CopyBuildinTagFiles; buildReport.Summary.AutoCollectShaders = AssetBundleCollectorSettingData.Setting.AutoCollectShaders; buildReport.Summary.ShadersBundleName = AssetBundleCollectorSettingData.Setting.ShadersBundleName; buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ? "null" : buildParameters.Parameters.EncryptionServices.GetType().FullName; // 构建参数 buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption; buildReport.Summary.DisableWriteTypeTree = buildParameters.Parameters.DisableWriteTypeTree; buildReport.Summary.IgnoreTypeTreeChanges = buildParameters.Parameters.IgnoreTypeTreeChanges; // 构建结果 buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount; buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(patchManifest); buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(patchManifest); buildReport.Summary.BuildinBundleTotalCount = GetBuildinBundleCount(patchManifest); buildReport.Summary.BuildinBundleTotalSize = GetBuildinBundleSize(patchManifest); buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(patchManifest); buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(patchManifest); buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(patchManifest); buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(patchManifest); } // 资源对象列表 buildReport.AssetInfos = new List <ReportAssetInfo>(patchManifest.AssetList.Count); foreach (var patchAsset in patchManifest.AssetList) { var mainBundle = patchManifest.BundleList[patchAsset.BundleID]; ReportAssetInfo reportAssetInfo = new ReportAssetInfo(); reportAssetInfo.Address = patchAsset.Address; reportAssetInfo.AssetPath = patchAsset.AssetPath; reportAssetInfo.AssetTags = patchAsset.AssetTags; reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(patchAsset.AssetPath); reportAssetInfo.MainBundleName = mainBundle.BundleName; reportAssetInfo.MainBundleSize = mainBundle.SizeBytes; reportAssetInfo.DependBundles = GetDependBundles(patchManifest, patchAsset); reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, patchAsset.AssetPath); buildReport.AssetInfos.Add(reportAssetInfo); } // 资源包列表 buildReport.BundleInfos = new List <ReportBundleInfo>(patchManifest.BundleList.Count); foreach (var patchBundle in patchManifest.BundleList) { ReportBundleInfo reportBundleInfo = new ReportBundleInfo(); reportBundleInfo.BundleName = patchBundle.BundleName; reportBundleInfo.Hash = patchBundle.Hash; reportBundleInfo.CRC = patchBundle.CRC; reportBundleInfo.SizeBytes = patchBundle.SizeBytes; reportBundleInfo.Tags = patchBundle.Tags; reportBundleInfo.Flags = patchBundle.Flags; buildReport.BundleInfos.Add(reportBundleInfo); } // 删除旧文件 string filePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetReportFileName(buildParameters.Parameters.BuildVersion)}"; if (File.Exists(filePath)) { File.Delete(filePath); } // 序列化文件 BuildReport.Serialize(filePath, buildReport); BuildRunner.Log($"资源构建报告文件创建完成:{filePath}"); }