Esempio n. 1
0
        /// <summary>
        /// Gets the path of the cache data from a selected build.
        /// </summary>
        /// <param name="browse">If true, the user is allowed to browse for a specific file.</param>
        /// <returns></returns>
        public static string GetContentStateDataPath(bool browse)
        {
            var assetPath = AddressableAssetSettingsDefaultObject.kDefaultConfigFolder;

            if (AddressableAssetSettingsDefaultObject.Settings != null)
            {
                assetPath = AddressableAssetSettingsDefaultObject.Settings.ConfigFolder;
            }
            assetPath = Path.Combine(assetPath, PlatformMappingService.GetPlatform().ToString());

            if (browse)
            {
                if (string.IsNullOrEmpty(assetPath))
                {
                    assetPath = Application.dataPath;
                }

                assetPath = EditorUtility.OpenFilePanel("Build Data File", Path.GetDirectoryName(assetPath), "bin");

                if (string.IsNullOrEmpty(assetPath))
                {
                    return(null);
                }

                return(assetPath);
            }

            Directory.CreateDirectory(assetPath);
            var path = Path.Combine(assetPath, "addressables_content_state.bin");

            return(path);
        }
        public async UniTask Load(string domain, string catalogName)
        {
            var uri = $"{domain}/{PlatformMappingService.GetPlatform()}/{catalogName}";

            while (true)
            {
                var operation = Addressables.LoadContentCatalogAsync(uri);
                await operation.Task;
                if (operation.OperationException != null)
                {
                    var errorResult =
                        await errorRequester.Request(ErrorMessage.Create(ErrorStatus.Fatal,
                                                                         operation.OperationException));

                    if (errorResult == ErrorResult.Retry)
                    {
                        continue;
                    }
                    else if (errorResult == ErrorResult.Error)
                    {
                        throw operation.OperationException;
                    }
                }

                Addressables.AddResourceLocator(operation.Result);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the path of the cache data from a selected build.
        /// </summary>
        /// <param name="browse">If true, the user is allowed to browse for a specific file.</param>
        /// <returns></returns>
        public static string GetContentStateDataPath(bool browse)
        {
            string assetPath = AddressableAssetSettingsDefaultObject.Settings != null?
                               AddressableAssetSettingsDefaultObject.Settings.GetContentStateBuildPath() :
                                   Path.Combine(AddressableAssetSettingsDefaultObject.kDefaultConfigFolder, PlatformMappingService.GetPlatformPathSubFolder());

            if (browse)
            {
                if (string.IsNullOrEmpty(assetPath))
                {
                    assetPath = Application.dataPath;
                }

                assetPath = EditorUtility.OpenFilePanel("Build Data File", Path.GetDirectoryName(assetPath), "bin");

                if (string.IsNullOrEmpty(assetPath))
                {
                    return(null);
                }

                return(assetPath);
            }

            if (AddressableAssetSettingsDefaultObject.Settings != null)
            {
                try
                {
                    Directory.CreateDirectory(assetPath);
                }
                catch (Exception e)
                {
                    Debug.LogError(e.Message + "\nCheck \"Content State Build Path\" in Addressables settings. Falling back to config folder location.");
                    assetPath = Path.Combine(AddressableAssetSettingsDefaultObject.kDefaultConfigFolder,
                                             PlatformMappingService.GetPlatformPathSubFolder());
                    Directory.CreateDirectory(assetPath);
                }
            }
            else
            {
                Directory.CreateDirectory(assetPath);
            }

            var path = Path.Combine(assetPath, "addressables_content_state.bin");

            return(path);
        }
        public void WhenBundleLocalCatalogEnabled_BuildScriptPacked_DoesNotCreatePerformanceLogReport()
        {
            string logPath = $"Library/com.unity.addressables/aa/{PlatformMappingService.GetPlatformPathSubFolder()}/buildlogtep.json";

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

            Settings.BundleLocalCatalog = true;

            var             context = new AddressablesDataBuilderInput(Settings);
            BuildScriptBase db      = (BuildScriptBase)Settings.DataBuilders.Find(x => x.GetType() == typeof(BuildScriptPackedMode));

            Assert.IsFalse(File.Exists(logPath)); // make sure file does not exist before build

            var res = db.BuildData <AddressablesPlayerBuildResult>(context);

            Assert.IsFalse(File.Exists(logPath));
        }
Esempio n. 5
0
    public override async Task <bool> Process(PipeContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        if (context.setting == null)
        {
            throw new System.ArgumentNullException("context.setting");
        }

        string stateAssetPath = context.setting.ConfigFolder;

        stateAssetPath = Path.Combine(stateAssetPath, PlatformMappingService.GetPlatform().ToString());
        var  content_state_path = Path.Combine(stateAssetPath, "addressables_content_state.bin");
        var  result             = ContentUpdateScript.BuildContentUpdate(context.setting, content_state_path);
        bool buildSuccess       = result != null && string.IsNullOrEmpty(result.Error);

        await Task.FromResult(true);

        return(buildSuccess);
    }
Esempio n. 6
0
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask         extractData          = new ExtractDataTask();
            List <CachedAssetState> carryOverCachedState = new List <CachedAssetState>();
            var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Guid + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                using (m_Log.ScopedStep(LogLevel.Info, "ContentPipeline.BuildAssetBundles"))
                {
                    var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext, m_Log);

                    if (exitCode < ReturnCode.Success)
                    {
                        return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                    }
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    using (m_Log.ScopedStep(LogLevel.Info, "GenerateLocationListsTask.Run"))
                    {
                        progressTracker.UpdateTask("Generating Addressables Locations");
                        GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                    }

                var groups = aaContext.settings.groups.Where(g => g != null);

                using (m_Log.ScopedStep(LogLevel.Info, "PostProcessBundles"))
                    using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    {
                        progressTracker.UpdateTask("Post Processing AssetBundles");

                        Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry = new Dictionary <string, ContentCatalogDataEntry>();
                        foreach (var loc in aaContext.locations)
                        {
                            if (loc != null && loc.Keys[0] != null && loc.Keys[0] is string && !primaryKeyToCatalogEntry.ContainsKey((string)loc.Keys[0]))
                            {
                                primaryKeyToCatalogEntry[(string)loc.Keys[0]] = loc;
                            }
                        }

                        foreach (var assetGroup in groups)
                        {
                            if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out List <string> buildBundles))
                            {
                                List <string> outputBundles = new List <string>();
                                for (int i = 0; i < buildBundles.Count; ++i)
                                {
                                    var b = m_AllBundleInputDefs.FindIndex(inputDef =>
                                                                           buildBundles[i].StartsWith(inputDef.assetBundleName));
                                    outputBundles.Add(b >= 0 ? m_OutputAssetBundleNames[b] : buildBundles[i]);
                                }

                                PostProcessBundles(assetGroup, buildBundles, outputBundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry, primaryKeyToCatalogEntry);
                            }
                        }
                    }

                ProcessCatalogEntriesForBuild(aaContext, m_Log, groups, builderInput, extractData.WriteData, carryOverCachedState, m_BundleToInternalId);

                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            var contentCatalog = new ContentCatalogData(aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);

            //save catalog
            var jsonText = JsonUtility.ToJson(contentCatalog);

            CreateCatalogFiles(jsonText, builderInput, aaContext);

            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }

            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g != null && g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath, carryOverCachedState))
            {
                try {
                    var contentStatePath = ContentUpdateScript.GetContentStateDataPath(false);
                    File.Copy(tempPath, contentStatePath, true);
                    builderInput.Registry.AddFile(contentStatePath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }
 public void EditorPlatformMappingService_EqualsDesiredAddressablesPlatform(BuildTarget platform, AddressablesPlatform desiredPlatform)
 {
     Assert.AreEqual(PlatformMappingService.GetAddressablesPlatformInternal(platform), desiredPlatform);
 }
        public void BuildContentUpdate()
        {
            var group = Settings.CreateGroup("LocalStuff3", false, false, false, null);

            Settings.BuildRemoteCatalog     = true;
            Settings.RemoteCatalogBuildPath = new ProfileValueReference();
            Settings.RemoteCatalogBuildPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteBuildPath);
            Settings.RemoteCatalogLoadPath = new ProfileValueReference();
            Settings.RemoteCatalogLoadPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteLoadPath);
            var schema = group.AddSchema <BundledAssetGroupSchema>();

            schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
            schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
            group.AddSchema <ContentUpdateGroupSchema>().StaticContent = true;
            Settings.CreateOrMoveEntry(m_AssetGUID, group);
            var context = new AddressablesDataBuilderInput(Settings);

            var op = Settings.ActivePlayerDataBuilder.BuildData <AddressablesPlayerBuildResult>(context);

            Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
            var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";
            var buildOp  = ContentUpdateScript.BuildContentUpdate(Settings, tempPath);

            Assert.IsNotNull(buildOp);
            Assert.IsTrue(string.IsNullOrEmpty(buildOp.Error));
        }
        public void PrepareContentUpdate()
        {
            var group  = Settings.CreateGroup("LocalStuff2", false, false, false, null);
            var schema = group.AddSchema <BundledAssetGroupSchema>();

            schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
            schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
            group.AddSchema <ContentUpdateGroupSchema>().StaticContent = true;

            var entry = Settings.CreateOrMoveEntry(m_AssetGUID, group);

            entry.address = "test";

            var context = new AddressablesDataBuilderInput(Settings);

            Settings.ActivePlayerDataBuilder.BuildData <AddressablesPlayerBuildResult>(context);

            var path = AssetDatabase.GUIDToAssetPath(m_AssetGUID);
            var obj  = AssetDatabase.LoadAssetAtPath <GameObject>(path);

            obj.GetComponent <Transform>().SetPositionAndRotation(new Vector3(10, 10, 10), Quaternion.identity);
#if UNITY_2018_3_OR_NEWER
            PrefabUtility.SavePrefabAsset(obj);
#else
            EditorUtility.SetDirty(obj);
#endif
            AssetDatabase.SaveAssets();
            var tempPath        = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";
            var modifiedEntries = ContentUpdateScript.GatherModifiedEntries(Settings, tempPath);
            Assert.IsNotNull(modifiedEntries);
            Assert.GreaterOrEqual(modifiedEntries.Count, 1);
            ContentUpdateScript.CreateContentUpdateGroup(Settings, modifiedEntries, "Content Update");
            var contentGroup = Settings.FindGroup("Content Update");
            Assert.IsNotNull(contentGroup);
            var movedEntry = contentGroup.GetAssetEntry(m_AssetGUID);
            Assert.AreSame(movedEntry, entry);
        }
Esempio n. 10
0
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask extractData = new ExtractDataTask();
            var             tempPath    = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext);

                if (exitCode < ReturnCode.Success)
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);

                foreach (var assetGroup in aaContext.settings.groups)
                {
                    List <string> bundles;
                    if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out bundles))
                    {
                        PostProcessBundles(assetGroup, bundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry);
                        PostProcessCatalogEnteries(assetGroup, extractData.WriteData, aaContext.locations, builderInput.Registry);
                    }
                }
                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            //save catalog
            var contentCatalog = new ContentCatalogData(aaContext.locations);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);
            CreateCatalog(aaContext.settings, contentCatalog, aaContext.runtimeData.CatalogLocations, playerBuildVersion, builderInput.RuntimeCatalogFilename, builderInput.Registry);
            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }
            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath))
            {
                try
                {
                    File.Copy(tempPath, ContentUpdateScript.GetContentStateDataPath(false), true);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }
Esempio n. 11
0
    public string GetAssetBundlePathAtStreamingAsset(string assetBundleName)
    {
        string location = Addressables.RuntimePath + "/" + PlatformMappingService.GetPlatform() + "/" + assetBundleName;

        return(location);
    }
Esempio n. 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);
        }
    }
 public void RuntimePlatformMappingService_EqualsDesiredAddressablesPlatform(RuntimePlatform platform, AddressablesPlatform desiredPlatform)
 {
     Assert.AreEqual(PlatformMappingService.GetAddressablesPlatformInternal(platform), desiredPlatform);
 }