TaskUpdateBundleInfo.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. namespace YooAsset.Editor
  7. {
  8. [TaskAttribute("更新资源包信息")]
  9. public class TaskUpdateBundleInfo : IBuildTask
  10. {
  11. void IBuildTask.Run(BuildContext context)
  12. {
  13. var buildParametersContext = context.GetContextObject<BuildParametersContext>();
  14. var buildMapContext = context.GetContextObject<BuildMapContext>();
  15. string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
  16. string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
  17. int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
  18. // 1.检测文件名长度
  19. foreach (var bundleInfo in buildMapContext.Collection)
  20. {
  21. // NOTE:检测文件名长度不要超过260字符。
  22. string fileName = bundleInfo.BundleName;
  23. if (fileName.Length >= 260)
  24. throw new Exception($"The output bundle name is too long {fileName.Length} chars : {fileName}");
  25. }
  26. // 2.更新构建输出的文件路径
  27. foreach (var bundleInfo in buildMapContext.Collection)
  28. {
  29. bundleInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
  30. if (bundleInfo.IsEncryptedFile)
  31. bundleInfo.PackageSourceFilePath = bundleInfo.EncryptedFilePath;
  32. else
  33. bundleInfo.PackageSourceFilePath = bundleInfo.BuildOutputFilePath;
  34. }
  35. // 3.更新文件其它信息
  36. foreach (var bundleInfo in buildMapContext.Collection)
  37. {
  38. bundleInfo.PackageUnityHash = GetUnityHash(bundleInfo, context);
  39. bundleInfo.PackageUnityCRC = GetUnityCRC(bundleInfo, context);
  40. bundleInfo.PackageFileHash = GetBundleFileHash(bundleInfo.PackageSourceFilePath, buildParametersContext);
  41. bundleInfo.PackageFileCRC = GetBundleFileCRC(bundleInfo.PackageSourceFilePath, buildParametersContext);
  42. bundleInfo.PackageFileSize = GetBundleFileSize(bundleInfo.PackageSourceFilePath, buildParametersContext);
  43. }
  44. // 4.更新补丁包输出的文件路径
  45. foreach (var bundleInfo in buildMapContext.Collection)
  46. {
  47. string bundleName = bundleInfo.BundleName;
  48. string fileHash = bundleInfo.PackageFileHash;
  49. string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleName);
  50. string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash);
  51. bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}";
  52. }
  53. }
  54. private string GetUnityHash(BuildBundleInfo bundleInfo, BuildContext context)
  55. {
  56. var buildParametersContext = context.GetContextObject<BuildParametersContext>();
  57. var parameters = buildParametersContext.Parameters;
  58. var buildMode = parameters.BuildMode;
  59. if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
  60. return "00000000000000000000000000000000"; //32位
  61. if (bundleInfo.IsRawFile)
  62. {
  63. string filePath = bundleInfo.PackageSourceFilePath;
  64. return HashUtility.FileMD5(filePath);
  65. }
  66. if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
  67. {
  68. var buildResult = context.GetContextObject<TaskBuilding.BuildResultContext>();
  69. var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
  70. if (hash.isValid)
  71. return hash.ToString();
  72. else
  73. throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
  74. }
  75. else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
  76. {
  77. // 注意:当资源包的依赖列表发生变化的时候,ContentHash也会发生变化!
  78. var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
  79. if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
  80. return value.Hash.ToString();
  81. else
  82. throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
  83. }
  84. else
  85. {
  86. throw new System.NotImplementedException();
  87. }
  88. }
  89. private uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context)
  90. {
  91. var buildParametersContext = context.GetContextObject<BuildParametersContext>();
  92. var parameters = buildParametersContext.Parameters;
  93. var buildMode = parameters.BuildMode;
  94. if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
  95. return 0;
  96. if (bundleInfo.IsRawFile)
  97. return 0;
  98. if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
  99. {
  100. string filePath = bundleInfo.BuildOutputFilePath;
  101. if (BuildPipeline.GetCRCForAssetBundle(filePath, out uint crc))
  102. return crc;
  103. else
  104. throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
  105. }
  106. else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
  107. {
  108. var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
  109. if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
  110. return value.Crc;
  111. else
  112. throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
  113. }
  114. else
  115. {
  116. throw new System.NotImplementedException();
  117. }
  118. }
  119. private string GetBundleFileHash(string filePath, BuildParametersContext buildParametersContext)
  120. {
  121. var buildMode = buildParametersContext.Parameters.BuildMode;
  122. if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
  123. return "00000000000000000000000000000000"; //32位
  124. else
  125. return HashUtility.FileMD5(filePath);
  126. }
  127. private string GetBundleFileCRC(string filePath, BuildParametersContext buildParametersContext)
  128. {
  129. var buildMode = buildParametersContext.Parameters.BuildMode;
  130. if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
  131. return "00000000"; //8位
  132. else
  133. return HashUtility.FileCRC32(filePath);
  134. }
  135. private long GetBundleFileSize(string filePath, BuildParametersContext buildParametersContext)
  136. {
  137. var buildMode = buildParametersContext.Parameters.BuildMode;
  138. if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
  139. return 0;
  140. else
  141. return FileUtility.GetFileSize(filePath);
  142. }
  143. }
  144. }