/// <summary>
        /// 创建补丁清单文件到输出目录
        /// </summary>
        private void CreatePatchManifestFile(AssetBundleBuilder.BuildParametersContext buildParameters,
                                             TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext,
                                             AssetBundleManifest unityManifest)
        {
            // 创建新补丁清单
            PatchManifest patchManifest = new PatchManifest();

            patchManifest.ResourceVersion = buildParameters.BuildVersion;
            patchManifest.BundleList      = GetAllPatchBundle(buildParameters, buildMapContext, encryptionContext, unityManifest);
            patchManifest.VariantList     = GetAllPatchVariant(unityManifest);

            // 创建新文件
            string filePath = $"{buildParameters.OutputDirectory}/{PatchDefine.PatchManifestFileName}";

            BuildLogger.Log($"创建补丁清单文件:{filePath}");
            PatchManifest.Serialize(filePath, patchManifest);
        }
        /// <summary>
        /// 获取资源包列表
        /// </summary>
        private List <PatchBundle> GetAllPatchBundle(AssetBundleBuilder.BuildParametersContext buildParameters,
                                                     TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext,
                                                     AssetBundleManifest unityManifest)
        {
            List <PatchBundle> result = new List <PatchBundle>();

            // 加载DLC
            DLCManager dlcManager = new DLCManager();

            dlcManager.LoadAllDLC();

            // 加载旧补丁清单
            PatchManifest oldPatchManifest = AssetBundleBuilder.LoadPatchManifestFile(buildParameters);

            // 获取加密列表
            List <string> encryptList = encryptionContext.EncryptList;

            string[] allAssetBundles = unityManifest.GetAllAssetBundles();
            foreach (var bundleName in allAssetBundles)
            {
                string   path      = $"{buildParameters.OutputDirectory}/{bundleName}";
                string   hash      = HashUtility.FileMD5(path);
                string   crc       = HashUtility.FileCRC32(path);
                long     size      = FileUtility.GetFileSize(path);
                int      version   = buildParameters.BuildVersion;
                string[] assets    = buildMapContext.GetCollectAssetPaths(bundleName);
                string[] depends   = unityManifest.GetDirectDependencies(bundleName);
                string[] dlcLabels = dlcManager.GetAssetBundleDLCLabels(bundleName);

                // 创建标记位
                bool isEncrypted = encryptList.Contains(bundleName);
                int  flags       = PatchBundle.CreateFlags(isEncrypted);

                // 注意:如果文件没有变化使用旧版本号
                if (oldPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle oldElement))
                {
                    if (oldElement.Hash == hash)
                    {
                        version = oldElement.Version;
                    }
                }

                PatchBundle newElement = new PatchBundle(bundleName, hash, crc, size, version, flags, assets, depends, dlcLabels);
                result.Add(newElement);
            }

            return(result);
        }
        /// <summary>
        /// 获取资源包列表
        /// </summary>
        private List <PatchBundle> GetAllPatchBundle(AssetBundleBuilder.BuildParametersContext buildParameters,
                                                     TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext,
                                                     AssetBundleManifest unityManifest)
        {
            List <PatchBundle> result = new List <PatchBundle>();

            // 内置标记列表
            List <string> buildinTags = buildParameters.Parameters.GetBuildinTags();

            // 加载旧补丁清单
            PatchManifest oldPatchManifest = null;

            if (buildParameters.Parameters.IsForceRebuild == false)
            {
                oldPatchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory);
            }

            string[] allAssetBundles = unityManifest.GetAllAssetBundles();
            foreach (var bundleName in allAssetBundles)
            {
                string   path          = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
                string   hash          = HashUtility.FileMD5(path);
                string   crc           = HashUtility.FileCRC32(path);
                long     size          = FileUtility.GetFileSize(path);
                int      version       = buildParameters.Parameters.BuildVersion;
                string[] collectAssets = buildMapContext.GetCollectAssetPaths(bundleName);
                string[] depends       = unityManifest.GetDirectDependencies(bundleName);
                string[] tags          = buildMapContext.GetAssetTags(bundleName);
                bool     isEncrypted   = encryptionContext.IsEncryptFile(bundleName);
                bool     isBuildin     = IsBuildinBundle(tags, buildinTags);

                // 注意:如果文件没有变化使用旧版本号
                if (oldPatchManifest != null && oldPatchManifest.Bundles.TryGetValue(bundleName, out PatchBundle value))
                {
                    if (value.Hash == hash)
                    {
                        version = value.Version;
                    }
                }

                PatchBundle patchBundle = new PatchBundle(bundleName, hash, crc, size, version, collectAssets, depends, tags);
                patchBundle.SetFlagsValue(isEncrypted, isBuildin);
                result.Add(patchBundle);
            }

            return(result);
        }