/// <summary>
        /// 复制更新文件到补丁包目录
        /// </summary>
        private void CopyUpdateFiles(AssetBundleBuilder.BuildParametersContext buildParameters)
        {
            string packageDirectory = buildParameters.GetPackageDirectory();

            BuildLogger.Log($"开始复制更新文件到补丁包目录:{packageDirectory}");

            // 复制Readme文件
            {
                string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.ReadmeFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.ReadmeFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"复制Readme文件到:{destPath}");
            }

            // 复制PatchManifest文件
            {
                string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.PatchManifestFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.PatchManifestFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"复制PatchManifest文件到:{destPath}");
            }

            // 复制UnityManifest文件
            {
                string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.UnityManifestFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"复制UnityManifest文件到:{destPath}");
            }

            // 复制Manifest文件
            {
                string sourcePath = $"{buildParameters.OutputDirectory}/{PatchDefine.UnityManifestFileName}.manifest";
                string destPath   = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}.manifest";
                EditorTools.CopyFile(sourcePath, destPath, true);
            }

            // 复制所有更新文件
            int           progressBarCount    = 0;
            PatchManifest patchFile           = AssetBundleBuilder.LoadPatchManifestFile(buildParameters);
            int           patchFileTotalCount = patchFile.BundleList.Count;

            foreach (var patchBundle in patchFile.BundleList)
            {
                if (patchBundle.Version == buildParameters.BuildVersion)
                {
                    string sourcePath = $"{buildParameters.OutputDirectory}/{patchBundle.BundleName}";
                    string destPath   = $"{packageDirectory}/{patchBundle.Hash}";
                    EditorTools.CopyFile(sourcePath, destPath, true);
                    BuildLogger.Log($"复制更新文件到补丁包:{sourcePath}");

                    progressBarCount++;
                    EditorUtility.DisplayProgressBar("进度", $"拷贝更新文件 : {sourcePath}", (float)progressBarCount / patchFileTotalCount);
                }
            }
            EditorUtility.ClearProgressBar();
        }
        /// <summary>
        /// 拷贝补丁文件到补丁包目录
        /// </summary>
        private void CopyPatchFiles(AssetBundleBuilder.BuildParametersContext buildParameters)
        {
            string packageDirectory = buildParameters.GetPackageDirectory();

            BuildLogger.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}");

            // 拷贝Readme文件
            {
                string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.ReadmeFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.ReadmeFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"拷贝Readme文件到:{destPath}");
            }

            // 拷贝PatchManifest文件
            {
                string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.PatchManifestFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.PatchManifestFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"拷贝PatchManifest文件到:{destPath}");
            }

            // 拷贝UnityManifest序列化文件
            {
                string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.UnityManifestFileName}";
                string destPath   = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}";
                EditorTools.CopyFile(sourcePath, destPath, true);
                BuildLogger.Log($"拷贝UnityManifest文件到:{destPath}");
            }

            // 拷贝UnityManifest文本文件
            {
                string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{PatchDefine.UnityManifestFileName}.manifest";
                string destPath   = $"{packageDirectory}/{PatchDefine.UnityManifestFileName}.manifest";
                EditorTools.CopyFile(sourcePath, destPath, true);
            }

            // 拷贝所有补丁文件
            // 注意:拷贝的补丁文件都是需要玩家热更新的文件
            int           progressValue       = 0;
            PatchManifest patchManifest       = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory);
            int           patchFileTotalCount = patchManifest.BundleList.Count;

            foreach (var patchBundle in patchManifest.BundleList)
            {
                if (patchBundle.Version == buildParameters.Parameters.BuildVersion)
                {
                    string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{patchBundle.BundleName}";
                    string destPath   = $"{packageDirectory}/{patchBundle.Hash}";
                    EditorTools.CopyFile(sourcePath, destPath, true);
                    BuildLogger.Log($"拷贝补丁文件到补丁包:{patchBundle.BundleName}");
                    EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount);
                }
            }
            EditorTools.ClearProgressBar();
        }
        /// <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);
        }
        /// <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);
        }
        private List <string> EncryptFiles(AssetBundleManifest unityManifest, AssetBundleBuilder.BuildParametersContext buildParameters)
        {
            // 加密资源列表
            List <string> encryptList = new List <string>();

            // 如果没有设置加密类
            if (_encrypter == null)
            {
                return(encryptList);
            }

            BuildLogger.Log($"开始加密资源文件");
            int progressBarCount = 0;

            string[] allAssetBundles = unityManifest.GetAllAssetBundles();
            foreach (string assetName in allAssetBundles)
            {
                string filePath = $"{buildParameters.OutputDirectory}/{assetName}";
                if (_encrypter.Check(filePath))
                {
                    encryptList.Add(assetName);

                    // 通过判断文件合法性,规避重复加密一个文件
                    byte[] fileData = File.ReadAllBytes(filePath);
                    if (EditorTools.CheckBundleFileValid(fileData))
                    {
                        byte[] bytes = _encrypter.Encrypt(fileData);
                        File.WriteAllBytes(filePath, bytes);
                        BuildLogger.Log($"文件加密完成:{filePath}");
                    }
                }

                // 进度条
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"加密资源包:{progressBarCount}/{allAssetBundles.Length}", (float)progressBarCount / allAssetBundles.Length);
            }
            EditorUtility.ClearProgressBar();

            return(encryptList);
        }
Esempio n. 7
0
        /// <summary>
        /// 创建Readme文件到输出目录
        /// </summary>
        private void CreateReadmeFile(AssetBundleBuilder.BuildParametersContext buildParameters, AssetBundleBuilder.BuildOptionsContext buildOptions, AssetBundleManifest unityManifest)
        {
            string[] allAssetBundles = unityManifest.GetAllAssetBundles();

            // 删除旧文件
            string filePath = $"{buildParameters.OutputDirectory}/{PatchDefine.ReadmeFileName}";

            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            BuildLogger.Log($"创建说明文件:{filePath}");

            StringBuilder content = new StringBuilder();

            AppendData(content, $"构建平台:{buildParameters.BuildTarget}");
            AppendData(content, $"构建版本:{buildParameters.BuildVersion}");
            AppendData(content, $"构建时间:{DateTime.Now}");

            AppendData(content, "");
            AppendData(content, $"--着色器--");
            AppendData(content, $"IsCollectAllShaders:{AssetBundleCollectorSettingData.Setting.IsCollectAllShaders}");
            AppendData(content, $"ShadersBundleName:{AssetBundleCollectorSettingData.Setting.ShadersBundleName}");

            AppendData(content, "");
            AppendData(content, $"--配置信息--");
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
            {
                AssetBundleCollectorSetting.Collector wrapper = AssetBundleCollectorSettingData.Setting.Collectors[i];
                AppendData(content, $"Directory : {wrapper.CollectDirectory} | {wrapper.PackRuleClassName} | {wrapper.FilterRuleClassName}");
            }

            AppendData(content, "");
            AppendData(content, $"--构建参数--");
            AppendData(content, $"CompressOption:{buildOptions.CompressOption}");
            AppendData(content, $"IsForceRebuild:{buildOptions.IsForceRebuild}");
            AppendData(content, $"IsDisableWriteTypeTree:{buildOptions.IsDisableWriteTypeTree}");
            AppendData(content, $"IsIgnoreTypeTreeChanges:{buildOptions.IsIgnoreTypeTreeChanges}");

            AppendData(content, "");
            AppendData(content, $"--构建清单--");
            for (int i = 0; i < allAssetBundles.Length; i++)
            {
                AppendData(content, allAssetBundles[i]);
            }

            PatchManifest patchFile = AssetBundleBuilder.LoadPatchManifestFile(buildParameters);

            {
                AppendData(content, "");
                AppendData(content, $"--更新清单--");
                foreach (var patchBundle in patchFile.BundleList)
                {
                    if (patchBundle.Version == buildParameters.BuildVersion)
                    {
                        AppendData(content, patchBundle.BundleName);
                    }
                }

                AppendData(content, "");
                AppendData(content, $"--变体列表--");
                foreach (var variant in patchFile.VariantList)
                {
                    AppendData(content, variant.ToString());
                }
            }

            // 创建新文件
            File.WriteAllText(filePath, content.ToString(), Encoding.UTF8);
        }
        /// <summary>
        /// 加密文件
        /// </summary>
        private List <string> EncryptFiles(IAssetEncrypter encrypter, AssetBundleManifest unityManifest, AssetBundleBuilder.BuildParametersContext buildParameters)
        {
            // 加密资源列表
            List <string> encryptList = new List <string>();

            // 如果没有设置加密类
            if (encrypter == null)
            {
                return(encryptList);
            }

            BuildLogger.Log($"开始加密资源文件");
            string[] allAssetBundles = unityManifest.GetAllAssetBundles();
            int      progressValue   = 0;

            foreach (string bundleName in allAssetBundles)
            {
                string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleName}";
                if (encrypter.Check(filePath))
                {
                    encryptList.Add(bundleName);

                    // 注意:通过判断文件合法性,规避重复加密一个文件
                    byte[] fileData = File.ReadAllBytes(filePath);
                    if (EditorTools.CheckBundleFileValid(fileData))
                    {
                        byte[] bytes = encrypter.Encrypt(fileData);
                        File.WriteAllBytes(filePath, bytes);
                        BuildLogger.Log($"文件加密完成:{filePath}");
                    }
                }

                // 进度条
                EditorTools.DisplayProgressBar("加密资源包", ++progressValue, allAssetBundles.Length);
            }
            EditorTools.ClearProgressBar();

            return(encryptList);
        }