123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- using System;
- using System.Linq;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEditor.Build.Pipeline;
- using UnityEditor.Build.Pipeline.Interfaces;
- namespace YooAsset.Editor
- {
- [TaskAttribute("创建补丁清单文件")]
- public class TaskCreatePatchManifest : IBuildTask
- {
- void IBuildTask.Run(BuildContext context)
- {
- CreatePatchManifestFile(context);
- }
-
-
-
- private void CreatePatchManifestFile(BuildContext context)
- {
- var buildParameters = context.GetContextObject<BuildParametersContext>();
- int resourceVersion = buildParameters.Parameters.BuildVersion;
-
- PatchManifest patchManifest = new PatchManifest();
- patchManifest.FileVersion = YooAssetSettings.PatchManifestFileVersion;
- patchManifest.ResourceVersion = buildParameters.Parameters.BuildVersion;
- patchManifest.EnableAddressable = buildParameters.Parameters.EnableAddressable;
- patchManifest.OutputNameStyle = (int)buildParameters.Parameters.OutputNameStyle;
- patchManifest.BuildinTags = buildParameters.Parameters.BuildinTags;
- patchManifest.BundleList = GetAllPatchBundle(context);
- patchManifest.AssetList = GetAllPatchAsset(context, patchManifest);
-
- if (buildParameters.Parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
- {
- if(buildParameters.Parameters.BuildMode == EBuildMode.IncrementalBuild)
- {
- var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
- UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
- }
- }
-
- 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);
- }
-
-
-
- private List<PatchBundle> GetAllPatchBundle(BuildContext context)
- {
- var buildParameters = context.GetContextObject<BuildParametersContext>();
- var buildMapContext = context.GetContextObject<BuildMapContext>();
- var encryptionContext = context.GetContextObject<TaskEncryption.EncryptionContext>();
- List<PatchBundle> result = new List<PatchBundle>(1000);
- List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
- foreach (var bundleInfo in buildMapContext.BundleInfos)
- {
- var bundleName = bundleInfo.BundleName;
- string fileHash = GetBundleFileHash(bundleInfo, buildParameters);
- string fileCRC = GetBundleFileCRC(bundleInfo, buildParameters);
- long fileSize = GetBundleFileSize(bundleInfo, buildParameters);
- string[] tags = buildMapContext.GetBundleTags(bundleName);
- bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
- bool isBuildin = IsBuildinBundle(tags, buildinTags);
- bool isRawFile = bundleInfo.IsRawFile;
- PatchBundle patchBundle = new PatchBundle(bundleName, fileHash, fileCRC, fileSize, tags);
- patchBundle.SetFlagsValue(isEncrypted, isBuildin, isRawFile);
- result.Add(patchBundle);
- }
- return result;
- }
- private bool IsBuildinBundle(string[] bundleTags, List<string> buildinTags)
- {
-
- if (bundleTags.Length == 0)
- return true;
- foreach (var tag in bundleTags)
- {
- if (buildinTags.Contains(tag))
- return true;
- }
- return false;
- }
- private string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
- {
- var buildMode = buildParametersContext.Parameters.BuildMode;
- if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
- return "00000000000000000000000000000000";
- string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
- return HashUtility.FileMD5(filePath);
- }
- private string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
- {
- var buildMode = buildParametersContext.Parameters.BuildMode;
- if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
- return "00000000";
- string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
- return HashUtility.FileCRC32(filePath);
- }
- private long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
- {
- var buildMode = buildParametersContext.Parameters.BuildMode;
- if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
- return 0;
- string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
- return FileUtility.GetFileSize(filePath);
- }
-
-
-
- private List<PatchAsset> GetAllPatchAsset(BuildContext context, PatchManifest patchManifest)
- {
- var buildParameters = context.GetContextObject<BuildParametersContext>();
- var buildMapContext = context.GetContextObject<BuildMapContext>();
- 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;
- }
- private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PatchManifest patchManifest)
- {
- List<int> result = new List<int>();
- foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
- {
- if (dependAssetInfo.HasBundleName())
- {
- int bundleID = GetAssetBundleID(dependAssetInfo.GetBundleName(), patchManifest);
- if (mainBundleID != bundleID)
- {
- if (result.Contains(bundleID) == false)
- result.Add(bundleID);
- }
- }
- }
- return result.ToArray();
- }
- private int GetAssetBundleID(string bundleName, PatchManifest patchManifest)
- {
- for (int index = 0; index < patchManifest.BundleList.Count; index++)
- {
- if (patchManifest.BundleList[index].BundleName == bundleName)
- return index;
- }
- throw new Exception($"Not found bundle name : {bundleName}");
- }
-
-
-
- private void UpdateBuiltInBundleReference(PatchManifest patchManifest, IBundleBuildResults buildResults)
- {
-
- string shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName();
- List<string> shaderBundleReferenceList = new List<string>();
- foreach (var valuePair in buildResults.BundleInfos)
- {
- if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName))
- shaderBundleReferenceList.Add(valuePair.Key);
- }
-
- Predicate<PatchBundle> predicate = new Predicate<PatchBundle>(s => s.BundleName == shadersBunldeName);
- int shaderBundleId = patchManifest.BundleList.FindIndex(predicate);
- if (shaderBundleId == -1)
- throw new Exception("没有发现着色器资源包!");
-
- foreach (var patchAsset in patchManifest.AssetList)
- {
- List<string> dependBundles = GetPatchAssetAllDependBundles(patchManifest, patchAsset);
- List<string> conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList();
- if (conflictAssetPathList.Count > 0)
- {
- List<int> newDependIDs = new List<int>(patchAsset.DependIDs);
- if (newDependIDs.Contains(shaderBundleId) == false)
- newDependIDs.Add(shaderBundleId);
- patchAsset.DependIDs = newDependIDs.ToArray();
- }
- }
- }
- private List<string> GetPatchAssetAllDependBundles(PatchManifest patchManifest, PatchAsset patchAsset)
- {
- List<string> result = new List<string>();
- string mainBundle = patchManifest.BundleList[patchAsset.BundleID].BundleName;
- result.Add(mainBundle);
- foreach (var dependID in patchAsset.DependIDs)
- {
- string dependBundle = patchManifest.BundleList[dependID].BundleName;
- result.Add(dependBundle);
- }
- return result;
- }
- }
- }
|