Update editor code

调整加密文件的生成规则
pull/51/head
hevinci 2022-11-01 23:13:18 +08:00
parent b5f2174ed0
commit 3413157c67
15 changed files with 263 additions and 233 deletions

View File

@ -56,6 +56,7 @@ namespace YooAsset.Editor
new TaskBuilding(), //开始执行构建 new TaskBuilding(), //开始执行构建
new TaskVerifyBuildResult(), //验证构建结果 new TaskVerifyBuildResult(), //验证构建结果
new TaskEncryption(), //加密资源文件 new TaskEncryption(), //加密资源文件
new TaskUpdateBuildInfo(), //更新构建信息
new TaskCreatePatchManifest(), //创建清单文件 new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁包 new TaskCreatePatchPackage(), //制作补丁包
@ -71,6 +72,7 @@ namespace YooAsset.Editor
new TaskBuilding_SBP(), //开始执行构建 new TaskBuilding_SBP(), //开始执行构建
new TaskVerifyBuildResult_SBP(), //验证构建结果 new TaskVerifyBuildResult_SBP(), //验证构建结果
new TaskEncryption(), //加密资源文件 new TaskEncryption(), //加密资源文件
new TaskUpdateBuildInfo(), //更新构建信息
new TaskCreatePatchManifest(), //创建清单文件 new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁包 new TaskCreatePatchPackage(), //制作补丁包

View File

@ -64,27 +64,8 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public static string MakePipelineOutputDirectory(string outputRoot, string buildPackage, BuildTarget buildTarget, EBuildMode buildMode) public static string MakePipelineOutputDirectory(string outputRoot, string buildPackage, BuildTarget buildTarget, EBuildMode buildMode)
{ {
string result = $"{outputRoot}/{buildPackage}/{buildTarget}/{YooAssetSettings.OutputFolderName}"; string outputDirectory = $"{outputRoot}/{buildPackage}/{buildTarget}/{YooAssetSettings.OutputFolderName}";
if (buildMode == EBuildMode.DryRunBuild) return outputDirectory;
result += $"_{EBuildMode.DryRunBuild}";
else if (buildMode == EBuildMode.SimulateBuild)
result += $"_{EBuildMode.SimulateBuild}";
return result;
}
/// <summary>
/// 加载补丁清单文件
/// </summary>
internal static PatchManifest LoadPatchManifestFile(string fileDirectory, string packageName, string packageVersion)
{
string filePath = $"{fileDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(packageName, packageVersion)}";
if (File.Exists(filePath) == false)
{
throw new System.Exception($"Not found patch manifest file : {filePath}");
}
string jsonData = FileUtility.ReadFile(filePath);
return PatchManifest.Deserialize(jsonData);
} }
} }
} }

View File

@ -21,9 +21,8 @@ namespace YooAsset.Editor
var buildResult = builder.Run(buildParameters); var buildResult = builder.Run(buildParameters);
if (buildResult.Success) if (buildResult.Success)
{ {
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.PackageName, buildParameters.BuildTarget, buildParameters.BuildMode);
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion); string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string manifestFilePath = $"{pipelineOutputDirectory}/{manifestFileName}"; string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
return manifestFilePath; return manifestFilePath;
} }
else else

View File

@ -8,6 +8,40 @@ namespace YooAsset.Editor
{ {
public class BuildBundleInfo public class BuildBundleInfo
{ {
public class BuildPatchInfo
{
/// <summary>
/// 构建内容的哈希值
/// </summary>
public string ContentHash { set; get; }
/// <summary>
/// 文件哈希值
/// </summary>
public string PatchFileHash { set; get; }
/// <summary>
/// 文件哈希值
/// </summary>
public string PatchFileCRC { set; get; }
/// <summary>
/// 文件哈希值
/// </summary>
public long PatchFileSize { set; get; }
/// <summary>
/// 构建输出的文件路径
/// </summary>
public string BuildOutputFilePath { set; get; }
/// <summary>
/// 补丁包输出文件路径
/// </summary>
public string PatchOutputFilePath { set; get; }
}
/// <summary> /// <summary>
/// 资源包名称 /// 资源包名称
/// </summary> /// </summary>
@ -19,6 +53,17 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public readonly List<BuildAssetInfo> BuildinAssets = new List<BuildAssetInfo>(); public readonly List<BuildAssetInfo> BuildinAssets = new List<BuildAssetInfo>();
/// <summary>
/// 补丁文件信息
/// </summary>
public readonly BuildPatchInfo PatchInfo = new BuildPatchInfo();
/// <summary>
/// 加密生成文件的路径
/// 注意:如果未加密该路径为空
/// </summary>
public string EncryptedFilePath { set; get; } = string.Empty;
/// <summary> /// <summary>
/// 是否为原生文件 /// 是否为原生文件
/// </summary> /// </summary>
@ -36,9 +81,18 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 构建内容哈希值 /// 是否为加密文件
/// </summary> /// </summary>
public string ContentHash { set; get; } = "00000000000000000000000000000000"; //32位 public bool IsEncryptedFile
{
get
{
if (string.IsNullOrEmpty(EncryptedFilePath))
return false;
else
return true;
}
}
public BuildBundleInfo(string bundleName) public BuildBundleInfo(string bundleName)
@ -117,5 +171,16 @@ namespace YooAsset.Editor
build.assetNames = GetBuildinAssetPaths(); build.assetNames = GetBuildinAssetPaths();
return build; return build;
} }
/// <summary>
/// 创建PatchBundle类
/// </summary>
internal PatchBundle CreatePatchBundle()
{
string[] tags = GetBundleTags();
PatchBundle patchBundle = new PatchBundle(BundleName, PatchInfo.PatchFileHash, PatchInfo.PatchFileCRC, PatchInfo.PatchFileSize, tags);
patchBundle.SetFlagsValue(IsRawFile, IsEncryptedFile);
return patchBundle;
}
} }
} }

View File

@ -64,18 +64,6 @@ namespace YooAsset.Editor
return result; return result;
} }
/// <summary>
/// 获取资源包的分类标签列表
/// </summary>
public string[] GetBundleTags(string bundleName)
{
if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo))
{
return bundleInfo.GetBundleTags();
}
throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleName}");
}
/// <summary> /// <summary>
/// 获取AssetBundle内构建的资源路径列表 /// 获取AssetBundle内构建的资源路径列表
/// </summary> /// </summary>

View File

@ -25,15 +25,18 @@ namespace YooAsset.Editor
if (buildMode == EBuildMode.SimulateBuild) if (buildMode == EBuildMode.SimulateBuild)
return; return;
// 开始构建
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
BuildAssetBundleOptions buildOptions = buildParametersContext.GetPipelineBuildOptions(); BuildAssetBundleOptions buildOptions = buildParametersContext.GetPipelineBuildOptions();
AssetBundleManifest buildResults = BuildPipeline.BuildAssetBundles(pipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), buildOptions, buildParametersContext.Parameters.BuildTarget); AssetBundleManifest buildResults = BuildPipeline.BuildAssetBundles(pipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), buildOptions, buildParametersContext.Parameters.BuildTarget);
if (buildResults == null) if (buildResults == null)
{
throw new Exception("构建过程中发生错误!"); throw new Exception("构建过程中发生错误!");
}
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
string unityOutputManifestFilePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{YooAssetSettings.OutputFolderName}"; string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
if (System.IO.File.Exists(unityOutputManifestFilePath) == false) if (System.IO.File.Exists(unityOutputManifestFilePath) == false)
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!"); throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
} }
@ -43,10 +46,10 @@ namespace YooAsset.Editor
buildResultContext.UnityManifest = buildResults; buildResultContext.UnityManifest = buildResults;
context.SetContextObject(buildResultContext); context.SetContextObject(buildResultContext);
// 拷贝原生文件
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
CopyRawBundle(buildMapContext, buildParametersContext); CopyRawBundle(buildMapContext, buildParametersContext);
UpdateBuildBundleInfo(buildMapContext, buildParametersContext, buildResultContext);
} }
} }
@ -69,29 +72,5 @@ namespace YooAsset.Editor
} }
} }
} }
/// <summary>
/// 更新构建结果
/// </summary>
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
}
else
{
var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
if (hash.isValid)
bundleInfo.ContentHash = hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
}
}
} }
} }

View File

@ -46,10 +46,10 @@ namespace YooAsset.Editor
buildResultContext.Results = buildResults; buildResultContext.Results = buildResults;
context.SetContextObject(buildResultContext); context.SetContextObject(buildResultContext);
// 拷贝原生文件
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
CopyRawBundle(buildMapContext, buildParametersContext); CopyRawBundle(buildMapContext, buildParametersContext);
UpdateBuildBundleInfo(buildMapContext, buildParametersContext, buildResultContext);
} }
} }
@ -72,29 +72,5 @@ namespace YooAsset.Editor
} }
} }
} }
/// <summary>
/// 更新构建结果
/// </summary>
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
}
else
{
// 注意当资源包的依赖列表发生变化的时候ContentHash也会发生变化
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
bundleInfo.ContentHash = value.Hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
}
}
} }
} }

View File

@ -12,16 +12,21 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var patchManifestContext = context.GetContextObject<PatchManifestContext>();
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None) if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None)
{ {
CopyBuildinFilesToStreaming(buildParametersContext); CopyBuildinFilesToStreaming(buildParametersContext, patchManifestContext);
}
} }
} }
/// <summary> /// <summary>
/// 拷贝首包资源文件 /// 拷贝首包资源文件
/// </summary> /// </summary>
private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext) private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, PatchManifestContext patchManifestContext)
{ {
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption; ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
@ -30,7 +35,7 @@ namespace YooAsset.Editor
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion; string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
// 加载补丁清单 // 加载补丁清单
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(packageOutputDirectory, buildPackageName, buildPackageVersion); PatchManifest patchManifest = patchManifestContext.Manifest;
// 清空流目录 // 清空流目录
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)

View File

@ -8,6 +8,11 @@ using UnityEditor.Build.Pipeline.Interfaces;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public class PatchManifestContext : IContextObject
{
internal PatchManifest Manifest;
}
[TaskAttribute("创建补丁清单文件")] [TaskAttribute("创建补丁清单文件")]
public class TaskCreatePatchManifest : IBuildTask public class TaskCreatePatchManifest : IBuildTask
{ {
@ -24,7 +29,7 @@ namespace YooAsset.Editor
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
// 创建新补丁清单 // 创建新补丁清单
PatchManifest patchManifest = new PatchManifest(); PatchManifest patchManifest = new PatchManifest();
@ -47,19 +52,24 @@ namespace YooAsset.Editor
} }
// 创建补丁清单文件 // 创建补丁清单文件
string packageHash = string.Empty; string packageHash;
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
PatchManifest.Serialize(filePath, patchManifest); PatchManifest.Serialize(filePath, patchManifest);
packageHash = HashUtility.FileMD5(filePath); packageHash = HashUtility.FileMD5(filePath);
BuildRunner.Log($"创建补丁清单文件:{filePath}"); BuildRunner.Log($"创建补丁清单文件:{filePath}");
var patchManifestContext = new PatchManifestContext();
string jsonData = FileUtility.ReadFile(filePath);
patchManifestContext.Manifest = PatchManifest.Deserialize(jsonData);
context.SetContextObject(patchManifestContext);
} }
// 创建补丁清单哈希文件 // 创建补丁清单哈希文件
{ {
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, packageHash); FileUtility.CreateFile(filePath, packageHash);
BuildRunner.Log($"创建补丁清单哈希文件:{filePath}"); BuildRunner.Log($"创建补丁清单哈希文件:{filePath}");
} }
@ -67,7 +77,7 @@ namespace YooAsset.Editor
// 创建补丁清单版本文件 // 创建补丁清单版本文件
{ {
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName); string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
string filePath = $"{pipelineOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, buildParameters.PackageVersion); FileUtility.CreateFile(filePath, buildParameters.PackageVersion);
BuildRunner.Log($"创建补丁清单版本文件:{filePath}"); BuildRunner.Log($"创建补丁清单版本文件:{filePath}");
} }
@ -78,59 +88,17 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
private List<PatchBundle> GetAllPatchBundle(BuildContext context) private List<PatchBundle> GetAllPatchBundle(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
var encryptionContext = context.GetContextObject<TaskEncryption.EncryptionContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
List<PatchBundle> result = new List<PatchBundle>(1000); List<PatchBundle> result = new List<PatchBundle>(1000);
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.BundleInfos)
{ {
// NOTE检测路径长度不要超过260字符。 var patchBundle = bundleInfo.CreatePatchBundle();
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
if (filePath.Length >= 260)
throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}");
var bundleName = bundleInfo.BundleName;
string fileHash = GetBundleFileHash(bundleInfo, buildParametersContext);
string fileCRC = GetBundleFileCRC(bundleInfo, buildParametersContext);
long fileSize = GetBundleFileSize(bundleInfo, buildParametersContext);
string[] tags = buildMapContext.GetBundleTags(bundleName);
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
bool isRawFile = bundleInfo.IsRawFile;
PatchBundle patchBundle = new PatchBundle(bundleName, fileHash, fileCRC, fileSize, tags);
patchBundle.SetFlagsValue(isRawFile, isEncrypted);
result.Add(patchBundle); result.Add(patchBundle);
} }
return result; return result;
} }
private string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{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"; //8位
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{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.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
return FileUtility.GetFileSize(filePath);
}
/// <summary> /// <summary>
/// 获取资源列表 /// 获取资源列表

View File

@ -9,55 +9,24 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
CopyPatchFiles(buildParameters); CopyPatchFiles(buildParameters, buildMapContext);
} }
} }
/// <summary> /// <summary>
/// 拷贝补丁文件到补丁包目录 /// 拷贝补丁文件到补丁包目录
/// </summary> /// </summary>
private void CopyPatchFiles(BuildParametersContext buildParametersContext) private void CopyPatchFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{ {
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}"); BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}");
// 拷贝Report文件
{
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单文件
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单哈希文件
{
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
string sourcePath = $"{pipelineOutputDirectory}/{fileName}";
string destPath = $"{packageOutputDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{ {
// 拷贝构建日志 // 拷贝构建日志
@ -75,7 +44,7 @@ namespace YooAsset.Editor
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
} }
} }
else else if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{ {
// 拷贝UnityManifest序列化文件 // 拷贝UnityManifest序列化文件
{ {
@ -91,16 +60,17 @@ namespace YooAsset.Editor
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
} }
} }
else
{
throw new System.NotImplementedException();
}
// 拷贝所有补丁文件 // 拷贝所有补丁文件
int progressValue = 0; int progressValue = 0;
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.PackageName, buildParameters.PackageVersion); int patchFileTotalCount = buildMapContext.BundleInfos.Count;
int patchFileTotalCount = patchManifest.BundleList.Count; foreach (var bundleInfo in buildMapContext.BundleInfos)
foreach (var patchBundle in patchManifest.BundleList)
{ {
string sourcePath = $"{pipelineOutputDirectory}/{patchBundle.BundleName}"; EditorTools.CopyFile(bundleInfo.PatchInfo.BuildOutputFilePath, bundleInfo.PatchInfo.PatchOutputFilePath, true);
string destPath = $"{packageOutputDirectory}/{patchBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount); EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();

View File

@ -12,24 +12,25 @@ namespace YooAsset.Editor
{ {
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
var patchManifestContext = context.GetContextObject<PatchManifestContext>();
buildParameters.StopWatch(); buildParameters.StopWatch();
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode != EBuildMode.SimulateBuild) if (buildMode != EBuildMode.SimulateBuild)
{ {
CreateReportFile(buildParameters, buildMapContext); CreateReportFile(buildParameters, buildMapContext, patchManifestContext);
} }
float buildSeconds = buildParameters.GetBuildingSeconds(); float buildSeconds = buildParameters.GetBuildingSeconds();
BuildRunner.Info($"Build time consuming {buildSeconds} seconds."); BuildRunner.Info($"Build time consuming {buildSeconds} seconds.");
} }
private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, PatchManifestContext patchManifestContext)
{ {
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.PackageName, buildParameters.PackageVersion); PatchManifest patchManifest = patchManifestContext.Manifest;
BuildReport buildReport = new BuildReport(); BuildReport buildReport = new BuildReport();
// 概述信息 // 概述信息
@ -49,7 +50,6 @@ namespace YooAsset.Editor
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion; buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable; buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable;
buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName; buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ? buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName; "null" : buildParameters.EncryptionServices.GetType().FullName;
@ -104,7 +104,7 @@ namespace YooAsset.Editor
// 序列化文件 // 序列化文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{pipelineOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
BuildReport.Serialize(filePath, buildReport); BuildReport.Serialize(filePath, buildReport);
BuildRunner.Log($"资源构建报告文件创建完成:{filePath}"); BuildRunner.Log($"资源构建报告文件创建完成:{filePath}");
} }

View File

@ -9,19 +9,6 @@ namespace YooAsset.Editor
[TaskAttribute("资源包加密")] [TaskAttribute("资源包加密")]
public class TaskEncryption : IBuildTask public class TaskEncryption : IBuildTask
{ {
public class EncryptionContext : IContextObject
{
public List<string> EncryptList;
/// <summary>
/// 检测是否为加密文件
/// </summary>
public bool IsEncryptFile(string bundleName)
{
return EncryptList.Contains(bundleName);
}
}
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
@ -30,31 +17,20 @@ namespace YooAsset.Editor
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
EncryptionContext encryptionContext = new EncryptionContext(); EncryptingBundleFiles(buildParameters, buildMapContext);
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
context.SetContextObject(encryptionContext);
}
else
{
EncryptionContext encryptionContext = new EncryptionContext();
encryptionContext.EncryptList = new List<string>();
context.SetContextObject(encryptionContext);
} }
} }
/// <summary> /// <summary>
/// 加密文件 /// 加密文件
/// </summary> /// </summary>
private List<string> EncryptFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) private void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{ {
var encryptionServices = buildParametersContext.Parameters.EncryptionServices; var encryptionServices = buildParametersContext.Parameters.EncryptionServices;
// 加密资源列表
List<string> encryptList = new List<string>();
// 如果没有设置加密类 // 如果没有设置加密类
if (encryptionServices == null) if (encryptionServices == null)
return encryptList; return;
int progressValue = 0; int progressValue = 0;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
@ -68,27 +44,19 @@ namespace YooAsset.Editor
continue; continue;
} }
encryptList.Add(bundleInfo.BundleName);
// 注意:通过判断文件合法性,规避重复加密一个文件
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
string savePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt";
byte[] fileData = File.ReadAllBytes(filePath); byte[] fileData = File.ReadAllBytes(filePath);
if (EditorTools.CheckBundleFileValid(fileData)) byte[] encryptData = encryptionServices.Encrypt(fileData);
{ FileUtility.CreateFile(savePath, encryptData);
byte[] bytes = encryptionServices.Encrypt(fileData); bundleInfo.EncryptedFilePath = savePath;
File.WriteAllBytes(filePath, bytes); BuildRunner.Log($"Bundle文件加密完成{savePath}");
BuildRunner.Log($"文件加密完成:{filePath}");
}
} }
// 进度条 // 进度条
EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count); EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
if(encryptList.Count == 0)
UnityEngine.Debug.LogWarning($"没有发现需要加密的文件!");
return encryptList;
} }
} }
} }

View File

@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace YooAsset.Editor
{
[TaskAttribute("更新构建信息")]
public class TaskUpdateBuildInfo : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
// 1.检测路径长度
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
// NOTE检测路径长度不要超过260字符。
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
if (filePath.Length >= 260)
throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}");
}
// 2.更新构建输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsEncryptedFile)
bundleInfo.PatchInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath;
else
bundleInfo.PatchInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
}
// 3.更新文件其它信息
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string buildOutputFilePath = bundleInfo.PatchInfo.BuildOutputFilePath;
bundleInfo.PatchInfo.ContentHash = GetBundleContentHash(bundleInfo, context);
bundleInfo.PatchInfo.PatchFileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext);
}
// 4.更新补丁包输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string patchFileName = PatchManifest.CreateBundleFileName(outputNameStyle, bundleInfo.BundleName, bundleInfo.PatchInfo.PatchFileHash);
bundleInfo.PatchInfo.PatchOutputFilePath = $"{packageOutputDirectory}/{patchFileName}";
}
}
private string GetBundleContentHash(BuildBundleInfo bundleInfo, BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
if (bundleInfo.IsRawFile)
{
string filePath = bundleInfo.PatchInfo.BuildOutputFilePath;
return HashUtility.FileMD5(filePath);
}
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
var buildResult = context.GetContextObject<TaskBuilding.BuildResultContext>();
var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
if (hash.isValid)
return hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
// 注意当资源包的依赖列表发生变化的时候ContentHash也会发生变化
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
return value.Hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
else
{
throw new System.NotImplementedException();
}
}
private string GetBundleFileHash(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
else
return HashUtility.FileMD5(filePath);
}
private string GetBundleFileCRC(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位
else
return HashUtility.FileCRC32(filePath);
}
private long GetBundleFileSize(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return 0;
else
return FileUtility.GetFileSize(filePath);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4882f54fbf0bcb04680fb581deae4889
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -349,9 +349,9 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 文件移动 /// 移动文件
/// </summary> /// </summary>
public static void FileMoveTo(string filePath, string destPath) public static void MoveFile(string filePath, string destPath)
{ {
if (File.Exists(destPath)) if (File.Exists(destPath))
File.Delete(destPath); File.Delete(destPath);