using System; using System.Collections.Generic; using System.Linq; using HG; using HG.AssetManagement; using HG.AsyncOperations; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceLocations; namespace RoR2.ContentManagement; public class AddressablesDirectory : IAssetRepository { public class AddressablesLoadAsyncOperationWrapper : BaseAsyncOperation where TAsset : UnityEngine.Object { private AsyncOperationHandle[] handles; private int completionCount; private List results = new List(); public override float progress { get { float num = 0f; if (handles.Length == 0) { return 0f; } float num2 = 1f / (float)handles.Length; for (int i = 0; i < handles.Length; i++) { num += handles[i].PercentComplete * num2; } return num; } } public AddressablesLoadAsyncOperationWrapper(IReadOnlyList> handles) { if (handles.Count == 0) { this.handles = Array.Empty>(); Complete(Array.Empty()); return; } results = new List(handles.Count); this.handles = new AsyncOperationHandle[handles.Count]; Action> value = OnChildOperationCompleted; for (int i = 0; i < handles.Count; i++) { this.handles[i] = handles[i]; AsyncOperationHandle asyncOperationHandle = handles[i]; asyncOperationHandle.Completed += value; } } private void OnChildOperationCompleted(AsyncOperationHandle handle) { if ((bool)handle.Result) { results.Add(handle.Result); } completionCount++; if (completionCount == handles.Length) { Complete(results.ToArray()); } } } private string baseDirectory; private FilePathTree folderTree; private IResourceLocator[] resourceLocators = Array.Empty(); public AddressablesDirectory(string baseDirectory, IEnumerable resourceLocators) { baseDirectory = baseDirectory ?? string.Empty; if (baseDirectory.Length > 0 && !baseDirectory.EndsWith("/")) { throw new ArgumentException("'baseDirectory' must be empty or end with '/'. baseDirectory=\"" + baseDirectory + "\""); } this.baseDirectory = baseDirectory; this.resourceLocators = resourceLocators.ToArray(); List list = new List(); IResourceLocator[] array = this.resourceLocators; for (int i = 0; i < array.Length; i++) { foreach (object key in array[i].Keys) { if (key is string text && text.StartsWith(baseDirectory)) { list.Add(text); } } } folderTree = FilePathTree.Create(list); } public BaseAsyncOperation LoadAllAsync(string folderPath) where TAsset : UnityEngine.Object { List list = new List(); string folderPath2 = baseDirectory + folderPath; folderTree.GetEntriesInFolder(folderPath2, list); _ = list.Count; return IssueLoadOperationAsGroup(list); } private BaseAsyncOperation IssueLoadOperationAsGroup(List entriesToLoad) where TAsset : UnityEngine.Object { List locations = FilterPathsByType(entriesToLoad); List results = new List(); AsyncOperationHandle> loadOperationHandle = Addressables.LoadAssetsAsync(locations, delegate(TAsset result) { results.Add(result); }); ScriptedAsyncOperation resultOperation = new ScriptedAsyncOperation(() => loadOperationHandle.PercentComplete); loadOperationHandle.Completed += delegate { resultOperation.Complete(results.ToArray()); }; return resultOperation; } private BaseAsyncOperation IssueLoadOperationsIndividually(List entriesToLoad) where TAsset : UnityEngine.Object { List list = FilterPathsByType(entriesToLoad); AsyncOperationHandle[] array = new AsyncOperationHandle[list.Count]; for (int i = 0; i < list.Count; i++) { AsyncOperationHandle asyncOperationHandle = Addressables.LoadAssetAsync(list[i]); array[i] = asyncOperationHandle; } return new AddressablesLoadAsyncOperationWrapper(array); } private List FilterPathsByType(List paths) { Type typeFromHandle = typeof(TAsset); bool[] array = new bool[paths.Count]; List list = new List(); IResourceLocator[] array2 = resourceLocators; foreach (IResourceLocator resourceLocator in array2) { for (int j = 0; j < paths.Count; j++) { if (array[j] || !resourceLocator.Locate(paths[j], null, out var locations)) { continue; } for (int k = 0; k < locations.Count; k++) { IResourceLocation resourceLocation = locations[k]; if (typeFromHandle.IsAssignableFrom(resourceLocation.ResourceType)) { list.Add(resourceLocation); array[j] = true; break; } } } } return list; } }