/// <summary>
        /// write manifest into target path.
        /// </summary>
        static void WriteManifestFile(string path, IBundleBuildResults bundleResults, BuildTarget target, string remoteURL)
        {
            var manifest = new AssetbundleBuildManifest();

            manifest.BuildTarget = target.ToString();

            //we use unity provided dependency result for final check
            var deps = bundleResults.BundleInfos.ToDictionary(kv => kv.Key, kv => kv.Value.Dependencies.ToList());

            foreach (var result in bundleResults.BundleInfos)
            {
                var bundleInfo = new AssetbundleBuildManifest.BundleInfo();
                bundleInfo.BundleName   = result.Key;
                bundleInfo.Dependencies = Utility.CollectBundleDependencies(deps, result.Key);
                bundleInfo.Hash         = result.Value.Hash;
                bundleInfo.Size         = new FileInfo(result.Value.FileName).Length;
                manifest.BundleInfos.Add(bundleInfo);
            }

            //sort by size
            manifest.BundleInfos.Sort((a, b) => b.Size.CompareTo(a.Size));
            var manifestString = JsonUtility.ToJson(manifest);

            manifest.GlobalHash = Hash128.Compute(manifestString);
            manifest.BuildTime  = DateTime.UtcNow.Ticks;
            manifest.RemoteURL  = remoteURL;
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            File.WriteAllText(Utility.CombinePath(path, AssetbundleBuildSettings.ManifestFileName), JsonUtility.ToJson(manifest, true));
        }
Exemple #2
0
        /// <summary>
        /// write logs into target path.
        /// </summary>
        static void WriteLogFile(string path, IBundleBuildResults bundleResults)
        {
            var sb = new System.Text.StringBuilder();

            sb.AppendLine($"Build Time : {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
            sb.AppendLine();

            for (int i = 0; i < bundleResults.BundleInfos.Count; i++)
            {
                var bundleInfo  = bundleResults.BundleInfos.ElementAt(i);
                var writeResult = bundleResults.WriteResults.ElementAt(i);
                sb.AppendLine($"----File Path : {bundleInfo.Value.FileName}----");
                var assetDic = new Dictionary <string, ulong>();
                foreach (var file in writeResult.Value.serializedObjects)
                {
                    //skip nonassettype
                    if (file.serializedObject.fileType == UnityEditor.Build.Content.FileType.NonAssetType)
                    {
                        continue;
                    }

                    //gather size
                    var assetPath = AssetDatabase.GUIDToAssetPath(file.serializedObject.guid.ToString());
                    if (!assetDic.ContainsKey(assetPath))
                    {
                        assetDic.Add(assetPath, file.header.size);
                    }
                    else
                    {
                        assetDic[assetPath] += file.header.size;
                    }
                }

                //sort by it's size
                var sortedAssets = assetDic.OrderByDescending(kv => kv.Value).ThenBy(kv => kv.Key);

                foreach (var asset in sortedAssets)
                {
                    sb.AppendLine($"{(asset.Value * 0.000001f).ToString("0.00000").PadLeft(10)} mb - {asset.Key}");
                }

                sb.AppendLine();
            }

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            File.WriteAllText(Path.Combine(path, LogFileName), sb.ToString());
        }
        public static string Generate(AssetbundleBuildSettings settings, IBundleBuildResults result)
        {
            var linkGenerator = new LinkXmlGenerator();

            foreach (var writeResult in result.WriteResults)
            {
                linkGenerator.AddTypes(writeResult.Value.includedTypes);
            }

            var settingsPath = Application.dataPath.Remove(Application.dataPath.Length - 6) + AssetDatabase.GetAssetPath(settings);

            settingsPath = settingsPath.Remove(settingsPath.LastIndexOf('/'));
            var linkPath = $"{settingsPath}/link.xml";

            linkGenerator.Save(linkPath);
            AssetDatabase.Refresh();
            return(linkPath.Remove(0, Application.dataPath.Length - 6));
        }
        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);
            }
        }
Exemple #5
0
 public BuildResult(ReturnCode exitCode, IBundleBuildResults bundleBuildResults)
 {
     ExitCode           = exitCode;
     BundleBuildResults = bundleBuildResults;
 }
Exemple #6
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);
            }
        }
        /// <summary>
        /// Default implementation of generating Asset Bundles using the Scriptable Build Pipeline.
        /// </summary>
        /// <param name="parameters">Set of parameters used for building asset bundles.</param>
        /// <param name="content">Set of content and explicit asset bundle layout to build.</param>
        /// <param name="result">Results from building the content and explicit asset bundle layout.</param>
        /// <param name="taskList">Custom task list for building asset bundles.</param>
        /// <param name="contextObjects">Additional context objects to make available to the build.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode BuildAssetBundles(IBundleBuildParameters parameters, IBundleBuildContent content, out IBundleBuildResults result, IList <IBuildTask> taskList, params IContextObject[] contextObjects)
        {
            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (parameters == null)
            {
                result = null;
                BuildLogger.LogException(new ArgumentNullException("parameters"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (taskList.IsNullOrEmpty())
            {
                result = null;
                BuildLogger.LogException(new ArgumentException("Argument cannot be null or empty.", "taskList"));
                return(ReturnCode.Exception);
            }

            // Don't run if there are unsaved changes
            if (ValidationMethods.HasDirtyScenes())
            {
                result = null;
                return(ReturnCode.UnsavedChanges);
            }

            AssetDatabase.SaveAssets();

            ReturnCode exitCode;

            result = new BundleBuildResults();

            //    using (new SceneStateCleanup())
            using (new BuildInterfacesWrapper())
                using (var progressTracker = new ProgressTracker())
                    using (var buildCache = new BuildCache(parameters.CacheServerHost, parameters.CacheServerPort))
                    {
                        Directory.CreateDirectory(parameters.TempOutputFolder);

                        BuildContext buildContext;
                        try
                        {
                            buildContext = new BuildContext(contextObjects);
                            buildContext.SetContextObject(parameters);
                            buildContext.SetContextObject(content);
                            buildContext.SetContextObject(result);
                            buildContext.SetContextObject(progressTracker);
                            buildContext.SetContextObject(buildCache);
                            buildContext.SetContextObject(new Unity5PackedIdentifiers());
                            buildContext.SetContextObject(new BuildDependencyData());
                            buildContext.SetContextObject(new BundleWriteData());
                            buildContext.SetContextObject(BuildCallbacks);
                        }
                        catch (Exception e)
                        {
                            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
                            result = null;
                            BuildLogger.LogException(e);
                            return(ReturnCode.Exception);
                        }

                        exitCode = BuildTasksRunner.Validate(taskList, buildContext);
                        if (exitCode >= ReturnCode.Success)
                        {
                            exitCode = BuildTasksRunner.Run(taskList, buildContext);
                        }

                        if (Directory.Exists(parameters.TempOutputFolder))
                        {
                            Directory.Delete(parameters.TempOutputFolder, true);
                        }
                    }
            return(exitCode);
        }
        /// <summary>
        /// Default implementation of generating Asset Bundles using the Scriptable Build Pipeline.
        /// </summary>
        /// <param name="parameters">Set of parameters used for building asset bundles.</param>
        /// <param name="content">Set of content and explicit asset bundle layout to build.</param>
        /// <param name="result">Results from building the content and explicit asset bundle layout.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode BuildAssetBundles(IBundleBuildParameters parameters, IBundleBuildContent content, out IBundleBuildResults result)
        {
            var taskList = DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleCompatible);

            return(BuildAssetBundles(parameters, content, out result, taskList));
        }
        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);
            }
        }
        /// <summary>
        /// Default implementation of generating Asset Bundles using the Scriptable Build Pipeline.
        /// </summary>
        /// <param name="parameters">Set of parameters used for building asset bundles.</param>
        /// <param name="content">Set of content and explicit asset bundle layout to build.</param>
        /// <param name="result">Results from building the content and explicit asset bundle layout.</param>
        /// <param name="taskList">Custom task list for building asset bundles.</param>
        /// <param name="contextObjects">Additional context objects to make available to the build.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode BuildAssetBundles(IBundleBuildParameters parameters, IBundleBuildContent content, out IBundleBuildResults result, IList <IBuildTask> taskList, params IContextObject[] contextObjects)
        {
            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (parameters == null)
            {
                result = null;
                BuildLogger.LogException(new ArgumentNullException("parameters"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (taskList.IsNullOrEmpty())
            {
                result = null;
                BuildLogger.LogException(new ArgumentException("Argument cannot be null or empty.", "taskList"));
                return(ReturnCode.Exception);
            }

            // Don't run if there are unsaved changes
            if (ValidationMethods.HasDirtyScenes())
            {
                result = null;
                return(ReturnCode.UnsavedChanges);
            }

            AssetDatabase.SaveAssets();

            ReturnCode exitCode;

            result = new BundleBuildResults();

            using (new BuildInterfacesWrapper())
#if !CI_TESTRUNNER_PROJECT
                using (new SceneStateCleanup())
                    using (var progressTracker = new ProgressTracker())
#else
                using (var progressTracker = new ProgressLoggingTracker())
#endif
                        using (var buildCache = new BuildCache(parameters.CacheServerHost, parameters.CacheServerPort))
                        {
                            Directory.CreateDirectory(parameters.TempOutputFolder);

                            BuildContext buildContext;
                            try
                            {
                                buildContext = new BuildContext(contextObjects);
                                buildContext.SetContextObject(parameters);
                                buildContext.SetContextObject(content);
                                buildContext.SetContextObject(result);
                                buildContext.SetContextObject(progressTracker);
                                buildContext.SetContextObject(buildCache);
                                // If IDeterministicIdentifiers was passed in with contextObjects, don't add the default
                                if (!buildContext.ContainsContextObject(typeof(IDeterministicIdentifiers)))
                                {
                                    buildContext.SetContextObject(new Unity5PackedIdentifiers());
                                }
                                buildContext.SetContextObject(new BuildDependencyData());
                                buildContext.SetContextObject(new BundleWriteData());
                                buildContext.SetContextObject(BuildCallbacks);
                            }
                            catch (Exception e)
                            {
                                // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
                                result = null;
                                BuildLogger.LogException(e);
                                return(ReturnCode.Exception);
                            }

                            exitCode = BuildTasksRunner.Validate(taskList, buildContext);
                            if (exitCode >= ReturnCode.Success)
#if SBP_PROFILER_ENABLE
                            { exitCode = BuildTasksRunner.RunProfiled(taskList, buildContext); }
#else
                            { exitCode = BuildTasksRunner.Run(taskList, buildContext); }
#endif

                            if (Directory.Exists(parameters.TempOutputFolder))
                            {
                                Directory.Delete(parameters.TempOutputFolder, true);
                            }
                        }


            int  maximumSize      = EditorPrefs.GetInt("BuildCache.maximumSize", 200);
            long maximumCacheSize = maximumSize * 1073741824L; // gigabytes to bytes
            ThreadPool.QueueUserWorkItem(PruneCache, maximumCacheSize);
            return(exitCode);
        }
    /// <summary>
    /// The BundleBuildContent class contains information about all of the Assets you want to build into the BuildMap
    /// Assets are referenced to by a GUID object, and the Addresses can be obtained and modified by using a GUID to
    /// refer to each asset and identify its Address
    /// </summary>
    /// <param name="outputPath"></param>
    /// <param name="compressionMode"></param>
    /// <param name="buildTarget"></param>
    /// <param name="buildGroup"></param>
    /// <param name="results"></param>
    /// <returns></returns>
    public static ReturnCode BuildAssetBundles(string outputPath, CompressionType compressionMode, BuildTarget buildTarget, BuildTargetGroup buildGroup, out IBundleBuildResults results)
    {
        BundleBuildContent buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());

        // Go through assets content and set their address to its filename
        for (int i = 0; i < buildContent.Assets.Count; ++i)
        {
            GUID g = buildContent.Assets[i];
            // Get the current address as the full filepath and change it to just be the filename
            buildContent.Addresses[g] = Path.GetFileNameWithoutExtension(buildContent.Addresses[g]);
        }

        BundleBuildParameters buildParams = new BundleBuildParameters(buildTarget, buildGroup, outputPath);

        switch (compressionMode)
        {
        case CompressionType.None:
            buildParams.BundleCompression = BuildCompression.Uncompressed;
            break;

        case CompressionType.Lz4:
            buildParams.BundleCompression = BuildCompression.LZ4;
            break;

        default:
            buildParams.BundleCompression = BuildCompression.LZMA;
            break;
        }

        return(ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results));
    }
Exemple #12
0
 internal LegacyAssetBundleManifest(IBundleBuildResults results)
 {
     m_Details = new Dictionary <string, BundleDetails>(results.BundleInfos);
 }
Exemple #13
0
        /// <summary>
        /// Default implementation of generating Asset Bundles using the Scriptable Build Pipeline.
        /// </summary>
        /// <param name="parameters">Set of parameters used for building asset bundles.</param>
        /// <param name="content">Set of content and explicit asset bundle layout to build.</param>
        /// <param name="result">Results from building the content and explicit asset bundle layout.</param>
        /// <param name="taskList">Custom task list for building asset bundles.</param>
        /// <param name="contextObjects">Additional context objects to make available to the build.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode BuildAssetBundles(IBundleBuildParameters parameters, IBundleBuildContent content, out IBundleBuildResults result, IList <IBuildTask> taskList, params IContextObject[] contextObjects)
        {
            if (BuildPipeline.isBuildingPlayer)
            {
                result = null;
                BuildLogger.LogException(new InvalidOperationException("Cannot build asset bundles while a build is in progress"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (parameters == null)
            {
                result = null;
                BuildLogger.LogException(new ArgumentNullException("parameters"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (taskList.IsNullOrEmpty())
            {
                result = null;
                BuildLogger.LogException(new ArgumentException("Argument cannot be null or empty.", "taskList"));
                return(ReturnCode.Exception);
            }

            // Don't run if there are unsaved changes
            if (ValidationMethods.HasDirtyScenes())
            {
                result = null;
                return(ReturnCode.UnsavedChanges);
            }

            ThreadingManager.WaitForOutstandingTasks();
            BuildContext buildContext = new BuildContext(contextObjects);
            BuildLog     buildLog     = null;

            IBuildLogger logger;

            if (!buildContext.TryGetContextObject <IBuildLogger>(out logger))
            {
                logger = buildLog = new BuildLog();
                buildContext.SetContextObject(buildLog);
            }

            using (logger.ScopedStep(LogLevel.Info, "AssetDatabase.SaveAssets"))
                AssetDatabase.SaveAssets();

            ReturnCode exitCode;

            result = new BundleBuildResults();
            BuildCacheUtility.ClearCacheHashes();
            using (var interfacesWrapper = new BuildInterfacesWrapper())
#if !CI_TESTRUNNER_PROJECT
                using (new SceneStateCleanup())
                    using (var progressTracker = new ProgressTracker())
#else
                using (var progressTracker = new ProgressLoggingTracker())
#endif
                        using (var buildCache = new BuildCache(parameters.CacheServerHost, parameters.CacheServerPort))
                        {
                            Directory.CreateDirectory(parameters.TempOutputFolder);
                            Directory.CreateDirectory(parameters.ScriptOutputFolder);

                            try
                            {
                                buildContext.SetContextObject(parameters);
                                buildContext.SetContextObject(content);
                                buildContext.SetContextObject(result);
                                buildContext.SetContextObject(interfacesWrapper);
                                buildContext.SetContextObject(progressTracker);
                                buildContext.SetContextObject(buildCache);
                                // If IDeterministicIdentifiers was passed in with contextObjects, don't add the default
                                if (!buildContext.ContainsContextObject(typeof(IDeterministicIdentifiers)))
                                {
                                    buildContext.SetContextObject(parameters.ContiguousBundles ? new PrefabPackedIdentifiers() : (IDeterministicIdentifiers) new Unity5PackedIdentifiers());
                                }
                                buildContext.SetContextObject(new BuildDependencyData());
                                buildContext.SetContextObject(new BundleWriteData());
                                buildContext.SetContextObject(BuildCallbacks);
                                buildCache.SetBuildLogger(logger);
                            }
                            catch (Exception e)
                            {
                                // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
                                result = null;
                                BuildLogger.LogException(e);
                                return(ReturnCode.Exception);
                            }

                            exitCode = BuildTasksRunner.Validate(taskList, buildContext);
                            if (exitCode >= ReturnCode.Success)
#if SBP_PROFILER_ENABLE
                            { exitCode = BuildTasksRunner.RunProfiled(taskList, buildContext); }
#else
                            { exitCode = BuildTasksRunner.Run(taskList, buildContext); }
#endif

                            if (Directory.Exists(parameters.TempOutputFolder))
                            {
                                Directory.Delete(parameters.TempOutputFolder, true);
                            }

                            if (buildLog != null)
                            {
                                string buildLogPath = parameters.GetOutputFilePathForIdentifier("buildlogtep.json");
                                Directory.CreateDirectory(Path.GetDirectoryName(buildLogPath));
                                File.WriteAllText(parameters.GetOutputFilePathForIdentifier("buildlogtep.json"), buildLog.FormatForTraceEventProfiler());
                            }
                        }


            long maximumCacheSize = ScriptableBuildPipeline.maximumCacheSize * BuildCache.k_BytesToGigaBytes;
            BuildCache.PruneCache_Background(maximumCacheSize);
            return(exitCode);
        }
    public static ReturnCode BuildAssetBundles(string outputPath, CompressionType compressionMode, BuildTarget buildTarget, BuildTargetGroup buildGroup, out IBundleBuildResults results)
    {
        BundleBuildContent    buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());
        BundleBuildParameters buildParams  = new BundleBuildParameters(buildTarget, buildGroup, outputPath);

        SetupBuildCacheServer(buildParams);

        switch (compressionMode)
        {
        case CompressionType.None:
            buildParams.BundleCompression = BuildCompression.Uncompressed;
            break;

        case CompressionType.Lz4:
            buildParams.BundleCompression = BuildCompression.LZ4;
            break;

        default:
            buildParams.BundleCompression = BuildCompression.LZMA;
            break;
        }

        return(ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results));
    }
    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);
        }
    }