/// <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 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>
        /// 2. 创建补丁清单文件到输出目录
        /// </summary>
        private void CreatePatchManifestFile(AssetBundleManifest unityManifest, List <AssetInfo> buildMap, List <string> encryptList)
        {
            string[] allAssetBundles = unityManifest.GetAllAssetBundles();

            // 创建DLC管理器
            DLCManager dlcManager = new DLCManager();

            dlcManager.LoadAllDLC();

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

            // 创建新补丁清单
            PatchManifest newPatchManifest = new PatchManifest();

            // 写入版本信息
            newPatchManifest.ResourceVersion = BuildVersion;

            // 写入所有AssetBundle文件的信息
            for (int i = 0; i < allAssetBundles.Length; i++)
            {
                string   bundleName = allAssetBundles[i];
                string   path       = $"{OutputDirectory}/{bundleName}";
                string   md5        = HashUtility.FileMD5(path);
                uint     crc32      = HashUtility.FileCRC32(path);
                long     sizeBytes  = EditorTools.GetFileSize(path);
                int      version    = BuildVersion;
                string[] assetPaths = GetBundleAssetPaths(buildMap, bundleName);
                string[] depends    = unityManifest.GetDirectDependencies(bundleName);
                string[] dlcLabels  = dlcManager.GetAssetBundleDLCLabels(bundleName);

                // 创建标记位
                bool isEncrypted = encryptList.Contains(bundleName);
                bool isCollected = IsCollectBundle(buildMap, bundleName);
                int  flags       = PatchElement.CreateFlags(isEncrypted, isCollected);

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

                PatchElement newElement = new PatchElement(bundleName, md5, crc32, sizeBytes, version, flags, assetPaths, depends, dlcLabels);
                newPatchManifest.ElementList.Add(newElement);
            }

            // 写入所有变体信息
            {
                Dictionary <string, List <string> > variantInfos = GetVariantInfos(allAssetBundles);
                foreach (var pair in variantInfos)
                {
                    if (pair.Value.Count > 0)
                    {
                        string        bundleName = $"{pair.Key}.{ PatchDefine.AssetBundleDefaultVariant}";
                        List <string> variants   = pair.Value;
                        newPatchManifest.VariantList.Add(new PatchVariant(bundleName, variants));
                    }
                }
            }

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

            Log($"创建补丁清单文件:{filePath}");
            PatchManifest.Serialize(filePath, newPatchManifest);
        }