コード例 #1
0
        internal void InitializeBuildContext(AddressablesDataBuilderInput builderInput, out AddressableAssetsBuildContext aaContext)
        {
            var aaSettings = builderInput.AddressableSettings;

            m_AllBundleInputDefs     = new List <AssetBundleBuild>();
            m_OutputAssetBundleNames = new List <string>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData
            {
                CertificateHandlerType        = aaSettings.CertificateHandlerType,
                BuildTarget                   = builderInput.Target.ToString(),
                ProfileEvents                 = builderInput.ProfilerEventsEnabled,
                LogResourceManagerExceptions  = aaSettings.buildSettings.LogResourceManagerExceptions,
                DisableCatalogUpdateOnStartup = aaSettings.DisableCatalogUpdateOnStartup,
                IsLocalCatalogInBundle        = aaSettings.BundleLocalCatalog
            };

            m_Linker = new LinkXmlGenerator();
            m_Linker.SetTypeConversion(typeof(UnityEditor.Animations.AnimatorController), typeof(RuntimeAnimatorController));
            m_Linker.AddTypes(runtimeData.CertificateHandlerType);

            m_ResourceProviderData = new List <ObjectInitializationData>();
            aaContext = new AddressableAssetsBuildContext
            {
                settings           = aaSettings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = bundleToAssetGroup,
                locations          = new List <ContentCatalogDataEntry>(),
                providerTypes      = new HashSet <Type>()
            };

            m_CreatedProviderIds = new HashSet <string>();
        }
コード例 #2
0
 protected void Setup()
 {
     m_BuilderInput = new AddressablesDataBuilderInput(Settings);
     m_BuildScript  = ScriptableObject.CreateInstance <BuildScriptPackedMode>();
     m_BuildScript.InitializeBuildContext(m_BuilderInput, out m_BuildContext);
     m_RuntimeData = m_BuildContext.runtimeData;
 }
コード例 #3
0
        /// <inheritdoc />
        protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput builderInput)
        {
            TResult result = default(TResult);

            var timer = new Stopwatch();

            timer.Start();
            var aaSettings = builderInput.AddressableSettings;

            var locations = new List <ContentCatalogDataEntry>();

            m_AllBundleInputDefs     = new List <AssetBundleBuild>();
            m_OutputAssetBundleNames = new List <string>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData();

            runtimeData.CertificateHandlerType       = aaSettings.CertificateHandlerType;
            runtimeData.BuildTarget                  = builderInput.Target.ToString();
            runtimeData.ProfileEvents                = builderInput.ProfilerEventsEnabled;
            runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions;
            m_Linker = new LinkXmlGenerator();
            m_Linker.SetTypeConversion(typeof(UnityEditor.Animations.AnimatorController), typeof(RuntimeAnimatorController));
            m_Linker.AddTypes(runtimeData.CertificateHandlerType);

            m_ResourceProviderData = new List <ObjectInitializationData>();
            var aaContext = new AddressableAssetsBuildContext
            {
                settings           = aaSettings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = bundleToAssetGroup,
                locations          = locations,
                providerTypes      = new HashSet <Type>()
            };

            m_CreatedProviderIds = new HashSet <string>();
            var errorString = ProcessAllGroups(aaContext);

            if (!string.IsNullOrEmpty(errorString))
            {
                result = AddressableAssetBuildResult.CreateResult <TResult>(null, 0, errorString);
            }

            if (result == null)
            {
                result = DoBuild <TResult>(builderInput, aaContext);
            }

            if (result != null)
            {
                result.Duration = timer.Elapsed.TotalSeconds;
            }

            return(result);
        }
        private AddressableAssetsBuildContext GetAddressableAssetsBuildContext(CheckBundleDupeDependencies rule)
        {
            ResourceManagerRuntimeData runtimeData = new ResourceManagerRuntimeData();

            runtimeData.LogResourceManagerExceptions = Settings.buildSettings.LogResourceManagerExceptions;
            var aaContext = new AddressableAssetsBuildContext
            {
                Settings           = Settings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = rule.m_BundleToAssetGroup,
                locations          = rule.m_Locations
            };

            return(aaContext);
        }
コード例 #5
0
        internal AddressableAssetsBuildContext GetBuildContext(AddressableAssetSettings settings)
        {
            ResourceManagerRuntimeData runtimeData = new ResourceManagerRuntimeData();

            runtimeData.LogResourceManagerExceptions = settings.buildSettings.LogResourceManagerExceptions;

            var aaContext = new AddressableAssetsBuildContext
            {
                settings           = settings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = m_BundleToAssetGroup,
                locations          = m_Locations
            };

            return(aaContext);
        }
コード例 #6
0
ファイル: BundleRuleBase.cs プロジェクト: Habi-Thapa/csv
        internal AddressableAssetsBuildContext GetBuildContext(AddressableAssetSettings settings)
        {
            ResourceManagerRuntimeData runtimeData = new ResourceManagerRuntimeData();
            runtimeData.LogResourceManagerExceptions = settings.buildSettings.LogResourceManagerExceptions;

            var aaContext = new AddressableAssetsBuildContext
            {
                Settings = settings,
                runtimeData = runtimeData,
                bundleToAssetGroup = m_BundleToAssetGroup,
                locations = m_Locations,
                providerTypes = new HashSet<Type>(),
                assetEntries = m_AssetEntries,
                assetGroupToBundles = new Dictionary<AddressableAssetGroup, List<string>>()
            };
            return aaContext;
        }
コード例 #7
0
        protected AddressableAssetsBuildContext GetBuildContext(AddressableAssetSettings settings)
        {
            ResourceManagerRuntimeData runtimeData = new ResourceManagerRuntimeData {
                LogResourceManagerExceptions = settings.buildSettings.LogResourceManagerExceptions
            };

            var aaContext = new AddressableAssetsBuildContext
            {
                Settings           = settings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = m_bundleToAssetGroup,
                locations          = m_locations,
                providerTypes      = new HashSet <Type>(),
                assetEntries       = m_assetEntries
            };

            return(aaContext);
        }
コード例 #8
0
        void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> buildBundles, List <string> outputBundles, IBundleBuildResults buildResult, IWriteData writeData, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry, Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry)
        {
            var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();

            if (schema == null)
            {
                return;
            }

            var path = schema.BuildPath.GetValue(assetGroup.Settings);

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            for (int i = 0; i < buildBundles.Count; ++i)
            {
                if (primaryKeyToCatalogEntry.TryGetValue(buildBundles[i], out ContentCatalogDataEntry dataEntry))
                {
                    var info           = buildResult.BundleInfos[buildBundles[i]];
                    var requestOptions = new AssetBundleRequestOptions
                    {
                        Crc             = schema.UseAssetBundleCrc ? info.Crc : 0,
                        Hash            = schema.UseAssetBundleCache ? info.Hash.ToString() : "",
                        ChunkedTransfer = schema.ChunkedTransfer,
                        RedirectLimit   = schema.RedirectLimit,
                        RetryCount      = schema.RetryCount,
                        Timeout         = schema.Timeout,
                        BundleName      = Path.GetFileName(info.FileName),
                        BundleSize      = GetFileSize(info.FileName)
                    };
                    dataEntry.Data = requestOptions;

                    int      extensionLength         = Path.GetExtension(outputBundles[i]).Length;
                    string[] deconstructedBundleName = outputBundles[i].Substring(0, outputBundles[i].Length - extensionLength).Split('_');
                    string   reconstructedBundleName = string.Join("_", deconstructedBundleName, 1, deconstructedBundleName.Length - 1) + ".bundle";

                    outputBundles[i]     = ConstructAssetBundleName(assetGroup, schema, info, reconstructedBundleName);
                    dataEntry.InternalId = dataEntry.InternalId.Remove(dataEntry.InternalId.Length - buildBundles[i].Length) + outputBundles[i];
                    dataEntry.Keys[0]    = outputBundles[i];
                    ReplaceDependencyKeys(buildBundles[i], outputBundles[i], locations);

                    if (!m_BundleToInternalId.ContainsKey(buildBundles[i]))
                    {
                        m_BundleToInternalId.Add(buildBundles[i], dataEntry.InternalId);
                    }

                    if (dataEntry.InternalId.StartsWith("http:\\"))
                    {
                        dataEntry.InternalId = dataEntry.InternalId.Replace("http:\\", "http://").Replace("\\", "/");
                    }
                    if (dataEntry.InternalId.StartsWith("https:\\"))
                    {
                        dataEntry.InternalId = dataEntry.InternalId.Replace("https:\\", "https://").Replace("\\", "/");
                    }
                }
                else
                {
                    Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", outputBundles[i]);
                }

                var targetPath = Path.Combine(path, outputBundles[i]);
                if (!Directory.Exists(Path.GetDirectoryName(targetPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                }
                File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, buildBundles[i]), targetPath, true);
                registry.AddFile(targetPath);
            }
        }
コード例 #9
0
        static void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> bundles, IBundleBuildResults buildResult, IWriteData writeData, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry)
        {
            var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();

            if (schema == null)
            {
                return;
            }

            var path = schema.BuildPath.GetValue(assetGroup.Settings);

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            foreach (var originalBundleName in bundles)
            {
                var newBundleName = originalBundleName;
                var info          = buildResult.BundleInfos[newBundleName];
                ContentCatalogDataEntry dataEntry = locations.FirstOrDefault(s => newBundleName == (string)s.Keys[0]);
                if (dataEntry != null)
                {
                    var requestOptions = new AssetBundleRequestOptions
                    {
                        Crc             = schema.UseAssetBundleCrc ? info.Crc : 0,
                        Hash            = schema.UseAssetBundleCache ? info.Hash.ToString() : "",
                        ChunkedTransfer = schema.ChunkedTransfer,
                        RedirectLimit   = schema.RedirectLimit,
                        RetryCount      = schema.RetryCount,
                        Timeout         = schema.Timeout,
                        BundleName      = Path.GetFileName(info.FileName),
                        BundleSize      = GetFileSize(info.FileName)
                    };
                    dataEntry.Data = requestOptions;

                    dataEntry.InternalId = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, info.Hash.ToString(), dataEntry.InternalId);
                    newBundleName        = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, info.Hash.ToString(), newBundleName);
                }
                else
                {
                    Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", newBundleName);
                }

                var targetPath = Path.Combine(path, newBundleName);
                if (!Directory.Exists(Path.GetDirectoryName(targetPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                }
                File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, originalBundleName), targetPath, true);
                registry.AddFile(targetPath);
            }
        }
コード例 #10
0
        static void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> bundles, IBundleBuildResults buildResult, IWriteData writeData, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry)
        {
            var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();

            if (schema == null)
            {
                return;
            }

            var path = schema.BuildPath.GetValue(assetGroup.Settings);

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            foreach (var originalBundleName in bundles)
            {
                var newBundleName = originalBundleName;
                var info          = buildResult.BundleInfos[newBundleName];
                ContentCatalogDataEntry dataEntry = locations.FirstOrDefault(s => newBundleName == (string)s.Keys[0]);
                if (dataEntry != null)
                {
                    var requestOptions = new AssetBundleRequestOptions
                    {
                        Crc             = schema.UseAssetBundleCrc ? info.Crc : 0,
                        Hash            = schema.UseAssetBundleCache ? info.Hash.ToString() : "",
                        ChunkedTransfer = schema.ChunkedTransfer,
                        RedirectLimit   = schema.RedirectLimit,
                        RetryCount      = schema.RetryCount,
                        Timeout         = schema.Timeout,
                        BundleName      = Path.GetFileName(info.FileName),
                        BundleSize      = GetFileSize(info.FileName)
                    };
                    dataEntry.Data = requestOptions;

                    int      extensionLength         = Path.GetExtension(originalBundleName).Length;
                    string[] deconstructedBundleName = originalBundleName.Substring(0, originalBundleName.Length - extensionLength)
                                                       .Split('_');
                    deconstructedBundleName[0] = assetGroup.Name
                                                 .Replace(" ", "")
                                                 .Replace('\\', '/')
                                                 .Replace("//", "/")
                                                 .ToLower();

                    string reconstructedBundleName = string.Join("_", deconstructedBundleName) + ".bundle";

                    newBundleName        = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, info.Hash.ToString(), reconstructedBundleName);
                    dataEntry.InternalId = dataEntry.InternalId.Remove(dataEntry.InternalId.Length - originalBundleName.Length) + newBundleName;

                    if (dataEntry.InternalId.StartsWith("http:\\"))
                    {
                        dataEntry.InternalId = dataEntry.InternalId.Replace("http:\\", "http://").Replace("\\", "/");
                    }
                }
                else
                {
                    Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", newBundleName);
                }

                var targetPath = Path.Combine(path, newBundleName);
                if (!Directory.Exists(Path.GetDirectoryName(targetPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                }
                File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, originalBundleName), targetPath, true);
                registry.AddFile(targetPath);
            }
        }
コード例 #11
0
        List <AnalyzeResult> DoFakeBuild(AddressableAssetSettings settings)
        {
            m_ImplicitAssets = new HashSet <GUID>();
            List <AnalyzeResult> emptyResult = new List <AnalyzeResult>();

            emptyResult.Add(new AnalyzeResult(ruleName + " - No issues found"));
            var context = new AddressablesDataBuilderInput(settings);
            var timer   = new Stopwatch();

            timer.Start();
            var aaSettings = context.AddressableSettings;

            //gather entries
            var locations          = new List <ContentCatalogDataEntry>();
            var allBundleInputDefs = new List <AssetBundleBuild>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData();

            runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions;

            foreach (var assetGroup in aaSettings.groups)
            {
                var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();
                if (schema == null)
                {
                    continue;
                }

                var bundleInputDefs = new List <AssetBundleBuild>();
                BuildScriptPackedMode.PrepGroupBundlePacking(assetGroup, bundleInputDefs, locations, schema.BundleMode);
                for (int i = 0; i < bundleInputDefs.Count; i++)
                {
                    if (bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName))
                    {
                        var bid     = bundleInputDefs[i];
                        int count   = 1;
                        var newName = bid.assetBundleName;
                        while (bundleToAssetGroup.ContainsKey(newName) && count < 1000)
                        {
                            newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++));
                        }
                        bundleInputDefs[i] = new AssetBundleBuild {
                            assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames
                        };
                    }

                    bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid);
                }
                allBundleInputDefs.AddRange(bundleInputDefs);
            }
            ExtractDataTask extractData = new ExtractDataTask();

            if (allBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    Debug.LogError("Cannot run Analyze with unsaved scenes");
                    return(emptyResult);
                }

                var buildTarget             = context.Target;
                var buildTargetGroup        = context.TargetGroup;
                var buildParams             = new AddressableAssetsBundleBuildParameters(aaSettings, bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath);
                var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                var aaContext = new AddressableAssetsBuildContext
                {
                    settings           = aaSettings,
                    runtimeData        = runtimeData,
                    bundleToAssetGroup = bundleToAssetGroup,
                    locations          = locations
                };

                IBundleBuildResults buildResults;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(allBundleInputDefs), out buildResults, buildTasks, aaContext);
                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                if (exitCode < ReturnCode.Success)
                {
                    Debug.LogError("Analyze build failed. " + exitCode);
                    return(emptyResult);
                }

                HashSet <GUID> explicitGuids = new HashSet <GUID>();
                foreach (var atf in extractData.WriteData.AssetToFiles)
                {
                    explicitGuids.Add(atf.Key);
                }

                Dictionary <GUID, List <string> > implicitGuids = new Dictionary <GUID, List <string> >();
                foreach (var fto in extractData.WriteData.FileToObjects)
                {
                    foreach (ObjectIdentifier g in fto.Value)
                    {
                        if (!explicitGuids.Contains(g.guid))
                        {
                            if (!implicitGuids.ContainsKey(g.guid))
                            {
                                implicitGuids.Add(g.guid, new List <string>());
                            }
                            implicitGuids[g.guid].Add(fto.Key);
                        }
                    }
                }

                //dictionary<group, dictionary<bundle, implicit assets >>
                Dictionary <string, Dictionary <string, List <string> > > allIssues = new Dictionary <string, Dictionary <string, List <string> > >();
                foreach (var g in implicitGuids)
                {
                    if (g.Value.Count > 1) //it's duplicated...
                    {
                        var path = AssetDatabase.GUIDToAssetPath(g.Key.ToString());
                        if (!AddressableAssetUtility.IsPathValidForEntry(path) ||
                            path.ToLower().Contains("/resources/") ||
                            path.ToLower().StartsWith("resources/"))
                        {
                            continue;
                        }

                        foreach (var file in g.Value)
                        {
                            var    bun = extractData.WriteData.FileToBundle[file];
                            string groupGuid;
                            if (aaContext.bundleToAssetGroup.TryGetValue(bun, out groupGuid))
                            {
                                var group = aaSettings.FindGroup(grp => grp.Guid == groupGuid);
                                if (group != null)
                                {
                                    Dictionary <string, List <string> > groupData;
                                    if (!allIssues.TryGetValue(group.Name, out groupData))
                                    {
                                        groupData = new Dictionary <string, List <string> >();
                                        allIssues.Add(group.Name, groupData);
                                    }

                                    List <string> assets;
                                    if (!groupData.TryGetValue(bun, out assets))
                                    {
                                        assets = new List <string>();
                                        groupData.Add(bun, assets);
                                    }
                                    assets.Add(path);

                                    m_ImplicitAssets.Add(g.Key);
                                }
                            }
                        }
                    }
                }

                List <AnalyzeResult> result = new List <AnalyzeResult>();
                foreach (var group in allIssues)
                {
                    foreach (var bundle in group.Value)
                    {
                        foreach (var item in bundle.Value)
                        {
                            var issueName = ruleName + kDelimiter + group.Key + kDelimiter + bundle.Key + kDelimiter + item;
                            result.Add(new AnalyzeResult(issueName, MessageType.Warning));
                        }
                    }
                }

                if (result.Count > 0)
                {
                    return(result);
                }
            }
            return(emptyResult);
        }
コード例 #12
0
    public override void PostProcessBundles(AddressableAssetGroup assetGroup, List <string> buildBundles, List <string> outputBundles, IBundleBuildResults buildResult, ResourceManagerRuntimeData runtimeData, List <ContentCatalogDataEntry> locations, FileRegistry registry, Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry, Dictionary <string, string> bundleRenameMap, List <Action> postCatalogUpdateCallbacks)
    {
        var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();

        if (schema == null)
        {
            return;
        }

        var path = schema.BuildPath.GetValue(assetGroup.Settings);

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        for (int i = 0; i < buildBundles.Count; ++i)
        {
            if (primaryKeyToCatalogEntry.TryGetValue(buildBundles[i], out ContentCatalogDataEntry dataEntry))
            {
                var info           = buildResult.BundleInfos[buildBundles[i]];
                var requestOptions = new AssetBundleEncryptRequestOptions
                {
                    Crc = schema.UseAssetBundleCrc ? info.Crc : 0,
                    UseCrcForCachedBundle = schema.UseAssetBundleCrcForCachedBundles,
                    Hash            = schema.UseAssetBundleCache ? info.Hash.ToString() : "",
                    ChunkedTransfer = schema.ChunkedTransfer,
                    RedirectLimit   = schema.RedirectLimit,
                    RetryCount      = schema.RetryCount,
                    Timeout         = schema.Timeout,
                    BundleName      = Path.GetFileName(info.FileName),
                    BundleSize      = GetFileSize(info.FileName)
                };
                dataEntry.Data = requestOptions;

                int      extensionLength         = Path.GetExtension(outputBundles[i]).Length;
                string[] deconstructedBundleName = outputBundles[i].Substring(0, outputBundles[i].Length - extensionLength).Split('_');
                string   reconstructedBundleName = string.Join("_", deconstructedBundleName, 1, deconstructedBundleName.Length - 1) + ".bundle";

                outputBundles[i]     = ConstructAssetBundleName(assetGroup, schema, info, reconstructedBundleName);
                dataEntry.InternalId = dataEntry.InternalId.Remove(dataEntry.InternalId.Length - buildBundles[i].Length) + outputBundles[i];
                dataEntry.Keys[0]    = outputBundles[i];
                ReplaceDependencyKeys(buildBundles[i], outputBundles[i], locations);

                Debug.Log(outputBundles[i] + "crc = " + requestOptions.Crc + " hash = " + requestOptions.Hash);

                if (!m_BundleToInternalId.ContainsKey(buildBundles[i]))
                {
                    m_BundleToInternalId.Add(buildBundles[i], dataEntry.InternalId);
                }

                if (dataEntry.InternalId.StartsWith("http:\\"))
                {
                    dataEntry.InternalId = dataEntry.InternalId.Replace("http:\\", "http://").Replace("\\", "/");
                }
                if (dataEntry.InternalId.StartsWith("https:\\"))
                {
                    dataEntry.InternalId = dataEntry.InternalId.Replace("https:\\", "https://").Replace("\\", "/");
                }
                dataEntry.InternalId = CheckNameNeedStripped(assetGroup, dataEntry.InternalId);
            }
            else
            {
                Debug.LogWarningFormat("Unable to find ContentCatalogDataEntry for bundle {0}.", outputBundles[i]);
            }

            //获取bundle的保存路径
            var targetPath = Path.Combine(path, outputBundles[i]);

            //判断目录是否存在
            if (!Directory.Exists(Path.GetDirectoryName(targetPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
            }

            File.Copy(Path.Combine(assetGroup.Settings.buildSettings.bundleBuildPath, buildBundles[i]), targetPath, true);

            var nameWithourHash = CheckNameNeedStripped(assetGroup, outputBundles[i]);
            EncodeAssetBundleBySetOffset(nameWithourHash, targetPath);
            var bundleName = Path.GetFileName(nameWithourHash);
            if (IsBuildInAssetBundle(bundleName))
            {
                string RuntimePath = UnityEngine.AddressableAssets.Addressables.RuntimePath;
                string destPath    = Path.Combine(System.Environment.CurrentDirectory, RuntimePath, PlatformMappingService.GetPlatform().ToString(), nameWithourHash);
                if (!Directory.Exists(Path.GetDirectoryName(destPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(destPath));
                }
                if (!File.Exists(destPath))
                {
                    File.Copy(targetPath, destPath);
                }
            }

            AddPostCatalogUpdatesInternal(assetGroup, postCatalogUpdateCallbacks, dataEntry, targetPath);

            registry.AddFile(targetPath);
        }
    }