internal static List <AssetEntryRevertOperation> DetermineRequiredAssetEntryUpdates(AddressableAssetGroup group, ContentUpdateScript.ContentUpdateContext contentUpdateContext)
    {
        if (!group.HasSchema <BundledAssetGroupSchema>())
        {
            return(new List <AssetEntryRevertOperation>());
        }

        bool groupIsStaticContentGroup = group.HasSchema <ContentUpdateGroupSchema>() && group.GetSchema <ContentUpdateGroupSchema>().StaticContent;
        List <AssetEntryRevertOperation> operations = new List <AssetEntryRevertOperation>();

        foreach (AddressableAssetEntry entry in group.entries)
        {
            GUID guid = new GUID(entry.guid);
            if (!contentUpdateContext.WriteData.AssetToFiles.ContainsKey(guid))
            {
                continue;
            }

            string file = contentUpdateContext.WriteData.AssetToFiles[guid][0];
            string fullInternalBundleName = contentUpdateContext.WriteData.FileToBundle[file];
            string finalBundleWritePath   = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName];

            //Ensure we can get the catalog entry for the bundle we're looking to replace
            if (!contentUpdateContext.IdToCatalogDataEntryMap.TryGetValue(finalBundleWritePath, out ContentCatalogDataEntry catalogBundleEntry))
            {
                continue;
            }

            //If new entries are added post initial build this will ensure that those new entries have their bundleFileId for SaveContentState
            entry.BundleFileId = catalogBundleEntry.InternalId;

            //If we have no cached state no reason to proceed.  This is new to the build.
            if (!contentUpdateContext.GuidToPreviousAssetStateMap.TryGetValue(entry.guid, out CachedAssetState previousAssetState))
            {
                continue;
            }

            //If the parent group is different we don't want to revert it to its previous state
            if (entry.parentGroup.Guid != previousAssetState.groupGuid)
            {
                continue;
            }

            //If the asset hash has changed and the group is not a static content update group we don't want to revert it to its previous state
            if (AssetDatabase.GetAssetDependencyHash(entry.AssetPath) != previousAssetState.asset.hash && !groupIsStaticContentGroup)
            {
                continue;
            }

            //If the previous asset state has the same bundle file id as the current build we don't want to revert it to its previous state
            if (catalogBundleEntry.InternalId == previousAssetState.bundleFileId)
            {
                continue;
            }

            var    schema    = group.GetSchema <BundledAssetGroupSchema>();
            string loadPath  = schema.LoadPath.GetValue(group.Settings);
            string buildPath = schema.BuildPath.GetValue(group.Settings);

            //Need to check and make sure our cached version exists
            if (string.IsNullOrEmpty(previousAssetState.bundleFileId))
            {
                //Logging this as an error because a CachedAssetState without a set bundleFileId is indicative of a significant issue with the build script.
                Addressables.LogError($"CachedAssetState found for {entry.AssetPath} but the bundleFileId was never set on the previous build.");
                continue;
            }

            string previousBundlePath = previousAssetState.bundleFileId?.Replace(loadPath, buildPath);

            if (!File.Exists(previousBundlePath))
            {
                //Logging this as a warning because users may choose to delete their bundles on disk which will trigger this state.
                Addressables.LogWarning($"CachedAssetState found for {entry.AssetPath} but the previous bundle at {previousBundlePath} cannot be found. " +
                                        $"The modified assets will not be able to use the previously built bundle which will result in new bundles being created " +
                                        $"for these static content groups.  This will point the Content Catalog to local bundles that do not exist on currently " +
                                        $"deployed versions of an application.");
                continue;
            }

            string builtBundlePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName].Replace(loadPath, buildPath);

            AssetEntryRevertOperation operation = new AssetEntryRevertOperation()
            {
                BundleCatalogEntry = catalogBundleEntry,
                AssetEntry         = entry,
                CurrentBuildPath   = builtBundlePath,
                PreviousAssetState = previousAssetState,
                PreviousBuildPath  = previousBundlePath
            };

            operations.Add(operation);
        }
        return(operations);
    }
Esempio n. 2
0
        private ContentUpdateScript.ContentUpdateContext GetContentUpdateContext(string contentUpdateTestAssetGUID, string contentUpdateTestCachedAssetHash,
                                                                                 string contentUpdateTestNewInternalBundleName, string contentUpdateTestNewBundleName, string contentUpdateTestCachedBundlePath, string contentUpdateTestGroupGuid, string contentUpdateTestFileName)
        {
            Dictionary <string, string> bundleToInternalBundle = new Dictionary <string, string>()
            {
                {
                    contentUpdateTestNewInternalBundleName,
                    contentUpdateTestNewBundleName
                }
            };

            Dictionary <string, CachedAssetState> guidToCachedState = new Dictionary <string, CachedAssetState>()
            {
                //entry 1
                {
                    contentUpdateTestAssetGUID, new CachedAssetState()
                    {
                        bundleFileId = contentUpdateTestCachedBundlePath,
                        asset        = new AssetState()
                        {
                            guid = new GUID(contentUpdateTestAssetGUID),
                            hash = Hash128.Parse(contentUpdateTestCachedAssetHash)
                        },
                        dependencies = new AssetState[] { },
                        data         = null,
                        groupGuid    = contentUpdateTestGroupGuid
                    }
                }
            };

            Dictionary <string, ContentCatalogDataEntry> idToCatalogEntryMap = new Dictionary <string, ContentCatalogDataEntry>()
            {
                //bundle entry
                { contentUpdateTestNewBundleName,
                  new ContentCatalogDataEntry(typeof(IAssetBundleResource), contentUpdateTestNewBundleName,
                                              typeof(AssetBundleProvider).FullName, new [] { contentUpdateTestNewBundleName }) },
                //asset entry
                {
                    contentUpdateTestAssetGUID,
                    new ContentCatalogDataEntry(typeof(IResourceLocation), contentUpdateTestAssetGUID, typeof(BundledAssetProvider).FullName, new [] { contentUpdateTestAssetGUID })
                }
            };

            IBundleWriteData writeData = new BundleWriteData();

            writeData.AssetToFiles.Add(new GUID(contentUpdateTestAssetGUID), new List <string>()
            {
                contentUpdateTestFileName
            });
            writeData.FileToBundle.Add(contentUpdateTestFileName, contentUpdateTestNewInternalBundleName);

            ContentUpdateScript.ContentUpdateContext context = new ContentUpdateScript.ContentUpdateContext()
            {
                WriteData = writeData,
                BundleToInternalBundleIdMap = bundleToInternalBundle,
                GuidToPreviousAssetStateMap = guidToCachedState,
                IdToCatalogDataEntryMap     = idToCatalogEntryMap,
                ContentState = new AddressablesContentState(),
                PreviousAssetStateCarryOver = new List <CachedAssetState>(),
                Registry = new FileRegistry()
            };
            return(context);
        }