From 34d74592ec9f00d62d437e7071c1b176641a833d Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Mon, 30 Mar 2026 23:49:09 -0500 Subject: [PATCH 1/6] Add multi-platform aware cache. --- .../BasisBEEExtensionMeta.cs | 1 + .../BasisBeeManagement.cs | 45 ++++++++- .../BasisIOManagement.cs | 50 +++++++++- .../BasisLoadhandler.cs | 93 ++++++++++++++----- .../BasisStorageManagement.cs | 87 +++++++++++------ 5 files changed, 218 insertions(+), 58 deletions(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs b/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs index 4217be46ce..0f0b556a88 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs @@ -7,4 +7,5 @@ public class BasisBEEExtensionMeta [SerializeField] public BasisStoredEncryptedBundle StoredLocal = new BasisStoredEncryptedBundle();//where we got bundle file from public string UniqueVersion; + public string DownloadedPlatform; } diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs index 8597c07537..aaaf255d10 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs @@ -5,6 +5,13 @@ using UnityEngine; public static class BasisBeeManagement { + private static bool HasCompatibleDownloadedPlatform(BasisBEEExtensionMeta metaInfo) + { + return metaInfo != null && + !string.IsNullOrEmpty(metaInfo.DownloadedPlatform) && + BasisBundleConnector.PlatformMatch(metaInfo.DownloadedPlatform); + } + /// /// this allows obtaining the entire bee file /// @@ -16,9 +23,16 @@ public static async Task HandleBundleAndMetaLoading(BasisTrackedBundleWrapper wr { bool IsMetaOnDisc = BasisLoadHandler.IsMetaDataOnDisc(wrapper.LoadableBundle.BasisRemoteBundleEncrypted.RemoteBeeFileLocation, out BasisBEEExtensionMeta MetaInfo); bool didForceRedownload = false; + bool shouldUseOnDiskMeta = IsMetaOnDisc; + + if (shouldUseOnDiskMeta && !HasCompatibleDownloadedPlatform(MetaInfo) && !string.IsNullOrEmpty(MetaInfo.DownloadedPlatform)) + { + BasisDebug.Log($"Cached bundle platform {MetaInfo.DownloadedPlatform} does not match {Application.platform}. Forcing re-download.", BasisDebug.LogTag.Event); + shouldUseOnDiskMeta = false; + } (BasisBundleGenerated, byte[], string) output; - if (IsMetaOnDisc) + if (shouldUseOnDiskMeta) { BasisDebug.Log("Process On Disc Meta Data Async", BasisDebug.LogTag.Event); output = await BasisBundleManagement.LocalLoadBundleConnector(wrapper, MetaInfo.StoredLocal, report, cancellationToken); @@ -54,7 +68,7 @@ public static async Task HandleBundleAndMetaLoading(BasisTrackedBundleWrapper wr { wrapper.AssetBundle = assetBundle; BasisDebug.Log($"we already have this AssetToLoadName in our loaded bundles using that instead! {AssetToLoadName}"); - await SaveMetaIfNeeded(wrapper, IsMetaOnDisc, didForceRedownload); + await SaveMetaIfNeeded(wrapper, shouldUseOnDiskMeta, didForceRedownload, output.Item1.Platform); return; } } @@ -63,10 +77,31 @@ public static async Task HandleBundleAndMetaLoading(BasisTrackedBundleWrapper wr try { AssetBundleCreateRequest bundleRequest = await BasisEncryptionToData.GenerateBundleFromFile(wrapper.LoadableBundle.UnlockPassword, output.Item2, output.Item1.AssetBundleCRC, report); + if (bundleRequest == null || bundleRequest.assetBundle == null) + { + if (shouldUseOnDiskMeta && !didForceRedownload) + { + BasisDebug.Log("Cached bundle bytes failed to load; forcing re-download.", BasisDebug.LogTag.Event); + output = await BasisBundleManagement.DownloadLoadBundleConnector(wrapper, report, cancellationToken, MaxDownloadSizeInBytes); + didForceRedownload = true; + + if (output.Item1 == null || output.Item2 == null || output.Item2.Length == 0 || !string.IsNullOrEmpty(output.Item3)) + { + throw new Exception($"Unable to reload bundle after cache mismatch. {output.Item3}"); + } + + bundleRequest = await BasisEncryptionToData.GenerateBundleFromFile(wrapper.LoadableBundle.UnlockPassword, output.Item2, output.Item1.AssetBundleCRC, report); + } + + if (bundleRequest == null || bundleRequest.assetBundle == null) + { + throw new Exception("AssetBundle creation failed after attempting to refresh the cached bundle."); + } + } wrapper.AssetBundle = bundleRequest.assetBundle; - await SaveMetaIfNeeded(wrapper, IsMetaOnDisc, didForceRedownload); + await SaveMetaIfNeeded(wrapper, shouldUseOnDiskMeta, didForceRedownload, output.Item1.Platform); } catch (Exception ex) { @@ -76,7 +111,7 @@ public static async Task HandleBundleAndMetaLoading(BasisTrackedBundleWrapper wr /// /// Saves or updates on-disc metadata when it is missing or was refreshed by a forced re-download. /// - private static async Task SaveMetaIfNeeded(BasisTrackedBundleWrapper wrapper, bool wasMetaOnDisc, bool didForceRedownload) + private static async Task SaveMetaIfNeeded(BasisTrackedBundleWrapper wrapper, bool wasMetaOnDisc, bool didForceRedownload, string downloadedPlatform) { if (!wasMetaOnDisc || didForceRedownload) { @@ -85,6 +120,7 @@ private static async Task SaveMetaIfNeeded(BasisTrackedBundleWrapper wrapper, bo StoredRemote = wrapper.LoadableBundle.BasisRemoteBundleEncrypted, StoredLocal = wrapper.LoadableBundle.BasisLocalEncryptedBundle, UniqueVersion = wrapper.LoadableBundle.BasisBundleConnector.UniqueVersion, + DownloadedPlatform = downloadedPlatform, }; await BasisLoadHandler.AddDiscInfo(newDiscInfo); @@ -124,6 +160,7 @@ public static async Task HandleMetaOnlyLoad(BasisTrackedBundleWrapper wrap StoredRemote = wrapper.LoadableBundle.BasisRemoteBundleEncrypted, StoredLocal = wrapper.LoadableBundle.BasisLocalEncryptedBundle, UniqueVersion = wrapper.LoadableBundle.BasisBundleConnector.UniqueVersion, + DownloadedPlatform = BasisIOManagement.GetCurrentCachePlatform(), }; await BasisLoadHandler.AddDiscInfo(newDiscInfo); diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs index 386e6eb4f8..d8decf01d2 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs @@ -7,6 +7,48 @@ public static class BasisIOManagement { + public static string GetCurrentCachePlatform() + { + return Application.platform.ToString(); + } + + public static string GetBeeCacheFilePath(string uniqueVersion, string downloadedPlatform = null) + { + return GenerateFilePath(BuildPlatformAwareCacheFileName(uniqueVersion, BasisBeeConstants.BasisEncryptedExtension, downloadedPlatform), BasisBeeConstants.AssetBundlesFolder); + } + + public static string GetMetaCacheFilePath(string uniqueVersion, string downloadedPlatform = null) + { + return GenerateFilePath(BuildPlatformAwareCacheFileName(uniqueVersion, BasisBeeConstants.BasisMetaExtension, downloadedPlatform), BasisBeeConstants.AssetBundlesFolder); + } + + public static string GetLegacyBeeCacheFilePath(string uniqueVersion) + { + return GenerateFilePath($"{uniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}", BasisBeeConstants.AssetBundlesFolder); + } + + public static string GetLegacyMetaCacheFilePath(string uniqueVersion) + { + return GenerateFilePath($"{uniqueVersion}{BasisBeeConstants.BasisMetaExtension}", BasisBeeConstants.AssetBundlesFolder); + } + + private static string BuildPlatformAwareCacheFileName(string uniqueVersion, string extension, string downloadedPlatform) + { + if (string.IsNullOrWhiteSpace(uniqueVersion)) + throw new ArgumentException("Unique version is null or empty.", nameof(uniqueVersion)); + + string normalizedPlatform = string.IsNullOrWhiteSpace(downloadedPlatform) + ? GetCurrentCachePlatform() + : downloadedPlatform.Trim(); + + foreach (char invalidChar in Path.GetInvalidFileNameChars()) + { + normalizedPlatform = normalizedPlatform.Replace(invalidChar, '_'); + } + + return $"{uniqueVersion}.{normalizedPlatform}{extension}"; + } + public sealed class BeeDownloadResult { public BasisBundleConnector Connector { get; } @@ -156,14 +198,14 @@ public static async Task> DownloadBEEEx(string url, } // 5) Write local .bee (Int32 header + connector + section) - string fileName = $"{connector.UniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}"; + string fileName = Path.GetFileName(GetBeeCacheFilePath(connector.UniqueVersion)); if (string.IsNullOrWhiteSpace(fileName)) return BeeResult.Fail("DownloadBEEEx: Connector has no UniqueVersion / file extension."); string localPath; try { - localPath = GenerateFilePath(fileName, BasisBeeConstants.AssetBundlesFolder); + localPath = GetBeeCacheFilePath(connector.UniqueVersion); } catch (Exception ex) { @@ -227,13 +269,13 @@ public static async Task> DownloadBEEEx(string url, } // 5) Write local .bee (Int32 header + connector + section) - string fileName = $"{connector.UniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}"; + string fileName = Path.GetFileName(GetBeeCacheFilePath(connector.UniqueVersion)); if (string.IsNullOrWhiteSpace(fileName)) { return BeeResult<(BasisBundleConnector, string)>.Fail("DownloadBEEEx: Connector has no UniqueVersion / file extension."); } - string localPath = GenerateFilePath(fileName, BasisBeeConstants.AssetBundlesFolder); + string localPath = GetBeeCacheFilePath(connector.UniqueVersion); var connectorBytes = connectorRes.Value.Data; var writeRes = await WriteBeeFileAsync(localPath, connectorBytes, null, true); diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs index f59f47b94a..ac6a19d86f 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs @@ -167,39 +167,84 @@ private static async Task HandleFirstBundleLoad(GameObject DisabledG BasisDebug.LogError($"{ex.Message} {ex.StackTrace}"); LoadedBundles.Remove(loadableBundle.BasisRemoteBundleEncrypted.RemoteBeeFileLocation, out var data); CleanupFiles(loadableBundle.BasisLocalEncryptedBundle); - OnDiscData.TryRemove(loadableBundle.BasisRemoteBundleEncrypted.RemoteBeeFileLocation, out _); return null; } } + + public static string GetDiscInfoKey(string remoteUrl, string downloadedPlatform) + { + string safeUrl = remoteUrl ?? string.Empty; + string safePlatform = string.IsNullOrWhiteSpace(downloadedPlatform) ? "legacy" : downloadedPlatform.Trim(); + return $"{safePlatform}|{safeUrl}"; + } + + private static bool TryResolveStoredBeePath(BasisBEEExtensionMeta discInfo, out string beePath) + { + beePath = discInfo.StoredLocal.DownloadedBeeFileLocation; + if (!string.IsNullOrWhiteSpace(beePath) && File.Exists(beePath)) + { + return true; + } + + if (!string.IsNullOrWhiteSpace(discInfo.UniqueVersion)) + { + string platformAwarePath = BasisIOManagement.GetBeeCacheFilePath(discInfo.UniqueVersion, discInfo.DownloadedPlatform); + if (File.Exists(platformAwarePath)) + { + discInfo.StoredLocal.DownloadedBeeFileLocation = platformAwarePath; + beePath = platformAwarePath; + return true; + } + + string legacyPath = BasisIOManagement.GetLegacyBeeCacheFilePath(discInfo.UniqueVersion); + if (File.Exists(legacyPath)) + { + discInfo.StoredLocal.DownloadedBeeFileLocation = legacyPath; + beePath = legacyPath; + return true; + } + } + + beePath = null; + return false; + } + public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta info) { lock (_discInfoLock) { + string currentPlatform = BasisIOManagement.GetCurrentCachePlatform(); + BasisBEEExtensionMeta legacyCandidate = null; + foreach (var discInfo in OnDiscData.Values) { if (discInfo.StoredRemote.RemoteBeeFileLocation == MetaURL) { - info = discInfo; - - if (string.IsNullOrEmpty(discInfo.StoredLocal.DownloadedBeeFileLocation)) + if (!string.IsNullOrWhiteSpace(discInfo.DownloadedPlatform) && + !string.Equals(discInfo.DownloadedPlatform, currentPlatform, StringComparison.OrdinalIgnoreCase)) { - string BEEPath = BasisIOManagement.GenerateFilePath($"{info.UniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}", BasisBeeConstants.AssetBundlesFolder); - if (File.Exists(BEEPath)) - { - discInfo.StoredLocal.DownloadedBeeFileLocation = BEEPath; - return true; - } + continue; } - else + + if (TryResolveStoredBeePath(discInfo, out _)) { - if (File.Exists(discInfo.StoredLocal.DownloadedBeeFileLocation)) + if (string.Equals(discInfo.DownloadedPlatform, currentPlatform, StringComparison.OrdinalIgnoreCase)) { + info = discInfo; return true; } + + legacyCandidate = discInfo; } } } + if (legacyCandidate != null) + { + info = legacyCandidate; + return true; + } + info = new BasisBEEExtensionMeta(); return false; } @@ -207,19 +252,21 @@ public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta in public static async Task AddDiscInfo(BasisBEEExtensionMeta discInfo) { - if (OnDiscData.TryAdd(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo)) - { - } - else - { - OnDiscData[discInfo.StoredRemote.RemoteBeeFileLocation] = discInfo; - BasisDebug.Log("Disc info updated.", BasisDebug.LogTag.Event); - } - string filePath = BasisIOManagement.GenerateFilePath($"{discInfo.UniqueVersion}{BasisBeeConstants.BasisMetaExtension}", BasisBeeConstants.AssetBundlesFolder); + string discKey = GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform); + OnDiscData[discKey] = discInfo; + string filePath = BasisIOManagement.GetMetaCacheFilePath(discInfo.UniqueVersion, discInfo.DownloadedPlatform); byte[] serializedData = BasisSerialization.SerializeValue(discInfo); try { + if (!string.IsNullOrWhiteSpace(discInfo.UniqueVersion)) + { + string legacyMetaPath = BasisIOManagement.GetLegacyMetaCacheFilePath(discInfo.UniqueVersion); + if (File.Exists(legacyMetaPath)) + { + File.Delete(legacyMetaPath); + } + } if (File.Exists(filePath)) { File.Delete(filePath); @@ -275,7 +322,7 @@ private static async Task LoadAllDiscData() { byte[] fileData = await File.ReadAllBytesAsync(file); BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); - OnDiscData.TryAdd(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo); + OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; } catch (Exception ex) { @@ -292,7 +339,7 @@ private static async Task LoadAllDiscData() private static void CleanupFiles(BasisStoredEncryptedBundle bundle) { - if (File.Exists(bundle.DownloadedBeeFileLocation)) + if (!string.IsNullOrWhiteSpace(bundle?.DownloadedBeeFileLocation) && File.Exists(bundle.DownloadedBeeFileLocation)) { File.Delete(bundle.DownloadedBeeFileLocation); } diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs index d7de86b5cd..f49d5d3c73 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs @@ -26,10 +26,12 @@ public static class BasisStorageManagement /// public class StoredBeeFileInfo { + public string DiscKey; public string RemoteUrl; public string LocalPath; public string MetaPath; public string UniqueVersion; + public string DownloadedPlatform; public long FileSizeBytes; public DateTime LastWriteTimeUtc; public bool IsLoadedInMemory; @@ -72,20 +74,18 @@ public static List GetAllStoredFiles() foreach (var kvp in BasisLoadHandler.OnDiscData) { + string discKey = kvp.Key; string remoteUrl = kvp.Key; BasisBEEExtensionMeta meta = kvp.Value; + remoteUrl = meta.StoredRemote.RemoteBeeFileLocation; string beePath = meta.StoredLocal.DownloadedBeeFileLocation; if (string.IsNullOrEmpty(beePath)) { - beePath = BasisIOManagement.GenerateFilePath( - $"{meta.UniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}", - BasisBeeConstants.AssetBundlesFolder); + beePath = BasisIOManagement.GetBeeCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); } - string metaFilePath = BasisIOManagement.GenerateFilePath( - $"{meta.UniqueVersion}{BasisBeeConstants.BasisMetaExtension}", - BasisBeeConstants.AssetBundlesFolder); + string metaFilePath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); long fileSize = 0; DateTime lastWrite = DateTime.MinValue; @@ -108,10 +108,12 @@ public static List GetAllStoredFiles() result.Add(new StoredBeeFileInfo { + DiscKey = discKey, RemoteUrl = remoteUrl, LocalPath = beePath, MetaPath = metaFilePath, UniqueVersion = meta.UniqueVersion, + DownloadedPlatform = meta.DownloadedPlatform, FileSizeBytes = fileSize, LastWriteTimeUtc = lastWrite, IsLoadedInMemory = isLoaded, @@ -133,28 +135,21 @@ public static bool DeleteStoredFile(string remoteUrl) if (string.IsNullOrEmpty(remoteUrl)) return false; - // Remove from OnDiscData and get the meta info - if (BasisLoadHandler.OnDiscData.TryRemove(remoteUrl, out BasisBEEExtensionMeta meta)) + bool removedAny = false; + foreach (var kvp in BasisLoadHandler.OnDiscData.ToList()) { - // Delete the .BEE file - string beePath = meta.StoredLocal.DownloadedBeeFileLocation; - if (string.IsNullOrEmpty(beePath)) + if (!string.Equals(kvp.Value.StoredRemote.RemoteBeeFileLocation, remoteUrl, StringComparison.Ordinal)) { - beePath = BasisIOManagement.GenerateFilePath( - $"{meta.UniqueVersion}{BasisBeeConstants.BasisEncryptedExtension}", - BasisBeeConstants.AssetBundlesFolder); + continue; } - TryDeleteFile(beePath); - // Delete the .BME meta file - string metaPath = BasisIOManagement.GenerateFilePath( - $"{meta.UniqueVersion}{BasisBeeConstants.BasisMetaExtension}", - BasisBeeConstants.AssetBundlesFolder); - TryDeleteFile(metaPath); - - BasisDebug.Log($"Deleted stored BEE file: {meta.UniqueVersion} (source: {remoteUrl})", BasisDebug.LogTag.Event); + if (DeleteStoredEntry(kvp.Key, kvp.Value)) + { + removedAny = true; + } } - else + + if (!removedAny) { BasisDebug.LogWarning($"No OnDiscData entry found for URL: {remoteUrl}", BasisDebug.LogTag.Event); return false; @@ -186,11 +181,27 @@ public static bool DeleteStoredFile(string remoteUrl) public static void ClearAllCache() { // Get all keys first to avoid concurrent modification - var keys = BasisLoadHandler.OnDiscData.Keys.ToList(); + var entries = BasisLoadHandler.OnDiscData.ToList(); - foreach (string key in keys) + foreach (var entry in entries) { - DeleteStoredFile(key); + DeleteStoredEntry(entry.Key, entry.Value); + } + + foreach (var loadedEntry in BasisLoadHandler.LoadedBundles.ToList()) + { + if (BasisLoadHandler.LoadedBundles.TryRemove(loadedEntry.Key, out BasisTrackedBundleWrapper wrapper) && + wrapper?.AssetBundle != null) + { + try + { + wrapper.AssetBundle.Unload(true); + } + catch (Exception ex) + { + BasisDebug.LogError($"Error unloading AssetBundle during cache clear: {ex.Message}"); + } + } } // Also clean up any orphaned files not tracked in OnDiscData @@ -229,7 +240,8 @@ public static void EnforceCacheSizeLimit() break; long freed = file.FileSizeBytes; - if (DeleteStoredFile(file.RemoteUrl)) + if (BasisLoadHandler.OnDiscData.TryGetValue(file.DiscKey, out BasisBEEExtensionMeta meta) && + DeleteStoredEntry(file.DiscKey, meta)) { currentSize -= freed; BasisDebug.Log($"Evicted: {file.UniqueVersion} ({FormatBytes(freed)}). Remaining: {FormatBytes(currentSize)}", BasisDebug.LogTag.Event); @@ -259,6 +271,27 @@ private static string GetCacheFolderPath() return BasisIOManagement.GenerateFolderPath(BasisBeeConstants.AssetBundlesFolder); } + private static bool DeleteStoredEntry(string discKey, BasisBEEExtensionMeta meta) + { + if (!BasisLoadHandler.OnDiscData.TryRemove(discKey, out _)) + { + return false; + } + + string beePath = meta.StoredLocal.DownloadedBeeFileLocation; + if (string.IsNullOrEmpty(beePath)) + { + beePath = BasisIOManagement.GetBeeCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); + } + TryDeleteFile(beePath); + + string metaPath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); + TryDeleteFile(metaPath); + + BasisDebug.Log($"Deleted stored BEE file: {meta.UniqueVersion} [{meta.DownloadedPlatform}] (source: {meta.StoredRemote.RemoteBeeFileLocation})", BasisDebug.LogTag.Event); + return true; + } + private static void TryDeleteFile(string path) { if (string.IsNullOrEmpty(path)) From b1dbc6f2daa1efea3b35fcfd88d4304cc3813eca Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Tue, 31 Mar 2026 02:09:29 -0500 Subject: [PATCH 2/6] Add Lazy-load if not finished with loading cache data. And add waits to apporiate locations that need the data. --- .../BasisLoadhandler.cs | 64 ++++++++++++++++++- .../BasisUI/Menus/Library/LibraryProvider.cs | 2 + .../Networking/BasisNetworkPreloadManager.cs | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs index ac6a19d86f..001c196046 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs @@ -209,6 +209,62 @@ private static bool TryResolveStoredBeePath(BasisBEEExtensionMeta discInfo, out return false; } + private static bool TryLazyLoadDiscInfo(string metaUrl, string currentPlatform, out BasisBEEExtensionMeta info) + { + info = null; + + string path = BasisIOManagement.GenerateFolderPath(BasisBeeConstants.AssetBundlesFolder); + if (!Directory.Exists(path)) + { + return false; + } + + BasisBEEExtensionMeta legacyCandidate = null; + + foreach (string file in Directory.GetFiles(path, $"*{BasisBeeConstants.BasisMetaExtension}")) + { + try + { + byte[] fileData = File.ReadAllBytes(file); + BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); + if (discInfo?.StoredRemote?.RemoteBeeFileLocation != metaUrl) + { + continue; + } + + OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; + + if (!TryResolveStoredBeePath(discInfo, out _)) + { + continue; + } + + if (BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform)) + { + info = discInfo; + return true; + } + + if (string.IsNullOrWhiteSpace(discInfo.DownloadedPlatform) && legacyCandidate == null) + { + legacyCandidate = discInfo; + } + } + catch (Exception ex) + { + BasisDebug.LogWarning($"Failed lazy-loading disc info from {file}: {ex.Message}", BasisDebug.LogTag.Event); + } + } + + if (legacyCandidate != null) + { + info = legacyCandidate; + return true; + } + + return false; + } + public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta info) { lock (_discInfoLock) @@ -245,6 +301,12 @@ public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta in return true; } + if (TryLazyLoadDiscInfo(MetaURL, currentPlatform, out BasisBEEExtensionMeta lazyLoadedInfo)) + { + info = lazyLoadedInfo; + return true; + } + info = new BasisBEEExtensionMeta(); return false; } @@ -285,7 +347,7 @@ public static void RemoveDiscInfo(string metaUrl) BasisStorageManagement.DeleteStoredFile(metaUrl); } - private static async Task EnsureInitializationComplete() + public static async Task EnsureInitializationComplete() { if (!IsInitialized) { diff --git a/Basis/Packages/com.basis.framework/BasisUI/Menus/Library/LibraryProvider.cs b/Basis/Packages/com.basis.framework/BasisUI/Menus/Library/LibraryProvider.cs index 8bb5cd0595..b9a6205a49 100644 --- a/Basis/Packages/com.basis.framework/BasisUI/Menus/Library/LibraryProvider.cs +++ b/Basis/Packages/com.basis.framework/BasisUI/Menus/Library/LibraryProvider.cs @@ -276,6 +276,8 @@ public static async Task LoadWrapperFromDisc(BasisDa wrapper = CreateNewWrapperFromItem(item); } + await BasisLoadHandler.EnsureInitializationComplete(); + // If the metadata is missing on disk, remove the key and DO NOT attempt to create a bundle from it. if (BasisLoadHandler.IsMetaDataOnDisc(item.Url, out BasisBEEExtensionMeta info)) { diff --git a/Basis/Packages/com.basis.framework/Networking/BasisNetworkPreloadManager.cs b/Basis/Packages/com.basis.framework/Networking/BasisNetworkPreloadManager.cs index ea69341736..78122fa63e 100644 --- a/Basis/Packages/com.basis.framework/Networking/BasisNetworkPreloadManager.cs +++ b/Basis/Packages/com.basis.framework/Networking/BasisNetworkPreloadManager.cs @@ -76,6 +76,8 @@ private static async Task HandlePreload(LocalLoadResource resource) BasisProgressReport report = new BasisProgressReport(); CancellationToken cancel = default; + await BasisLoadHandler.EnsureInitializationComplete(); + // Check if the full BEE file is already on disk bool isOnDisc = BasisLoadHandler.IsMetaDataOnDisc(resource.CombinedURL, out BasisBEEExtensionMeta metaInfo); From 01e1932f67e228f6b1e6e394797d02035a894eb4 Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Tue, 31 Mar 2026 02:09:56 -0500 Subject: [PATCH 3/6] Normalize/Match platforms to regular locations. --- .../BasisBeeManagement.cs | 2 +- .../BasisIOManagement.cs | 33 +++++++++++++++++-- .../BasisLoadhandler.cs | 4 +-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs index aaaf255d10..313b9eac24 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs @@ -9,7 +9,7 @@ private static bool HasCompatibleDownloadedPlatform(BasisBEEExtensionMeta metaIn { return metaInfo != null && !string.IsNullOrEmpty(metaInfo.DownloadedPlatform) && - BasisBundleConnector.PlatformMatch(metaInfo.DownloadedPlatform); + BasisIOManagement.CachePlatformMatchesCurrent(metaInfo.DownloadedPlatform); } /// diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs index d8decf01d2..86e5e5c666 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs @@ -9,7 +9,36 @@ public static class BasisIOManagement { public static string GetCurrentCachePlatform() { - return Application.platform.ToString(); + return NormalizeCachePlatformName(Application.platform.ToString()); + } + + public static bool CachePlatformMatchesCurrent(string downloadedPlatform) + { + return string.Equals(NormalizeCachePlatformName(downloadedPlatform), GetCurrentCachePlatform(), StringComparison.OrdinalIgnoreCase); + } + + public static string NormalizeCachePlatformName(string platformName) + { + if (string.IsNullOrWhiteSpace(platformName)) + { + return string.Empty; + } + + string normalized = platformName.Trim(); + return normalized switch + { + nameof(RuntimePlatform.WindowsEditor) => "StandaloneWindows64", + nameof(RuntimePlatform.WindowsPlayer) => "StandaloneWindows64", + nameof(RuntimePlatform.WindowsServer) => "StandaloneWindows64", + nameof(RuntimePlatform.LinuxEditor) => "StandaloneLinux64", + nameof(RuntimePlatform.LinuxPlayer) => "StandaloneLinux64", + nameof(RuntimePlatform.LinuxServer) => "StandaloneLinux64", + nameof(RuntimePlatform.OSXEditor) => "StandaloneOSX", + nameof(RuntimePlatform.OSXPlayer) => "StandaloneOSX", + nameof(RuntimePlatform.Android) => "Android", + nameof(RuntimePlatform.IPhonePlayer) => "iOS", + _ => normalized, + }; } public static string GetBeeCacheFilePath(string uniqueVersion, string downloadedPlatform = null) @@ -39,7 +68,7 @@ private static string BuildPlatformAwareCacheFileName(string uniqueVersion, stri string normalizedPlatform = string.IsNullOrWhiteSpace(downloadedPlatform) ? GetCurrentCachePlatform() - : downloadedPlatform.Trim(); + : NormalizeCachePlatformName(downloadedPlatform); foreach (char invalidChar in Path.GetInvalidFileNameChars()) { diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs index 001c196046..7fe2b6fc27 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs @@ -277,14 +277,14 @@ public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta in if (discInfo.StoredRemote.RemoteBeeFileLocation == MetaURL) { if (!string.IsNullOrWhiteSpace(discInfo.DownloadedPlatform) && - !string.Equals(discInfo.DownloadedPlatform, currentPlatform, StringComparison.OrdinalIgnoreCase)) + !BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform)) { continue; } if (TryResolveStoredBeePath(discInfo, out _)) { - if (string.Equals(discInfo.DownloadedPlatform, currentPlatform, StringComparison.OrdinalIgnoreCase)) + if (BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform)) { info = discInfo; return true; From 050d934f279ebccde5108f95192ecca65ad070fb Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Tue, 31 Mar 2026 02:39:47 -0500 Subject: [PATCH 4/6] Add multi-folder platform and improve default avatar loading by cache file instead of waiting for cache fill. --- .../BasisIOManagement.cs | 21 ++-- .../BasisLoadhandler.cs | 96 ++++++++++--------- .../BasisStorageManagement.cs | 7 +- .../com.basis.common/BasisDataStore.cs | 8 +- .../Players/Local/BasisLocalPlayer.cs | 18 +++- 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs index 86e5e5c666..c3b9053b87 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs @@ -43,12 +43,12 @@ public static string NormalizeCachePlatformName(string platformName) public static string GetBeeCacheFilePath(string uniqueVersion, string downloadedPlatform = null) { - return GenerateFilePath(BuildPlatformAwareCacheFileName(uniqueVersion, BasisBeeConstants.BasisEncryptedExtension, downloadedPlatform), BasisBeeConstants.AssetBundlesFolder); + return GenerateFilePath(BuildLegacyCacheFileName(uniqueVersion, BasisBeeConstants.BasisEncryptedExtension), GetPlatformCacheFolder(downloadedPlatform)); } public static string GetMetaCacheFilePath(string uniqueVersion, string downloadedPlatform = null) { - return GenerateFilePath(BuildPlatformAwareCacheFileName(uniqueVersion, BasisBeeConstants.BasisMetaExtension, downloadedPlatform), BasisBeeConstants.AssetBundlesFolder); + return GenerateFilePath(BuildLegacyCacheFileName(uniqueVersion, BasisBeeConstants.BasisMetaExtension), GetPlatformCacheFolder(downloadedPlatform)); } public static string GetLegacyBeeCacheFilePath(string uniqueVersion) @@ -61,21 +61,26 @@ public static string GetLegacyMetaCacheFilePath(string uniqueVersion) return GenerateFilePath($"{uniqueVersion}{BasisBeeConstants.BasisMetaExtension}", BasisBeeConstants.AssetBundlesFolder); } - private static string BuildPlatformAwareCacheFileName(string uniqueVersion, string extension, string downloadedPlatform) + private static string GetPlatformCacheFolder(string downloadedPlatform) { - if (string.IsNullOrWhiteSpace(uniqueVersion)) - throw new ArgumentException("Unique version is null or empty.", nameof(uniqueVersion)); - string normalizedPlatform = string.IsNullOrWhiteSpace(downloadedPlatform) ? GetCurrentCachePlatform() : NormalizeCachePlatformName(downloadedPlatform); - foreach (char invalidChar in Path.GetInvalidFileNameChars()) + foreach (char invalidChar in Path.GetInvalidPathChars()) { normalizedPlatform = normalizedPlatform.Replace(invalidChar, '_'); } - return $"{uniqueVersion}.{normalizedPlatform}{extension}"; + return Path.Combine(BasisBeeConstants.AssetBundlesFolder, normalizedPlatform); + } + + private static string BuildLegacyCacheFileName(string uniqueVersion, string extension) + { + if (string.IsNullOrWhiteSpace(uniqueVersion)) + throw new ArgumentException("Unique version is null or empty.", nameof(uniqueVersion)); + + return $"{uniqueVersion}{extension}"; } public sealed class BeeDownloadResult diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs index 7fe2b6fc27..bd33371339 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs @@ -209,60 +209,43 @@ private static bool TryResolveStoredBeePath(BasisBEEExtensionMeta discInfo, out return false; } - private static bool TryLazyLoadDiscInfo(string metaUrl, string currentPlatform, out BasisBEEExtensionMeta info) + private static bool TryLoadDiscInfoFromFile(string filePath, string expectedRemoteUrl, out BasisBEEExtensionMeta info) { info = null; - - string path = BasisIOManagement.GenerateFolderPath(BasisBeeConstants.AssetBundlesFolder); - if (!Directory.Exists(path)) + if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath)) { return false; } - BasisBEEExtensionMeta legacyCandidate = null; - - foreach (string file in Directory.GetFiles(path, $"*{BasisBeeConstants.BasisMetaExtension}")) + try { - try + byte[] fileData = File.ReadAllBytes(filePath); + BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); + if (discInfo?.StoredRemote?.RemoteBeeFileLocation == null) { - byte[] fileData = File.ReadAllBytes(file); - BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); - if (discInfo?.StoredRemote?.RemoteBeeFileLocation != metaUrl) - { - continue; - } - - OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; - - if (!TryResolveStoredBeePath(discInfo, out _)) - { - continue; - } - - if (BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform)) - { - info = discInfo; - return true; - } + return false; + } - if (string.IsNullOrWhiteSpace(discInfo.DownloadedPlatform) && legacyCandidate == null) - { - legacyCandidate = discInfo; - } + if (!string.IsNullOrWhiteSpace(expectedRemoteUrl) && + !string.Equals(discInfo.StoredRemote.RemoteBeeFileLocation, expectedRemoteUrl, StringComparison.Ordinal)) + { + return false; } - catch (Exception ex) + + OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; + if (!TryResolveStoredBeePath(discInfo, out _)) { - BasisDebug.LogWarning($"Failed lazy-loading disc info from {file}: {ex.Message}", BasisDebug.LogTag.Event); + return false; } - } - if (legacyCandidate != null) - { - info = legacyCandidate; + info = discInfo; return true; } - - return false; + catch (Exception ex) + { + BasisDebug.LogWarning($"Failed loading disc info from {filePath}: {ex.Message}", BasisDebug.LogTag.Event); + return false; + } } public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta info) @@ -301,14 +284,29 @@ public static bool IsMetaDataOnDisc(string MetaURL, out BasisBEEExtensionMeta in return true; } - if (TryLazyLoadDiscInfo(MetaURL, currentPlatform, out BasisBEEExtensionMeta lazyLoadedInfo)) + info = new BasisBEEExtensionMeta(); + return false; + } + } + + public static bool TryLoadMetaDataFromCacheFile(string uniqueVersion, string expectedRemoteUrl, out BasisBEEExtensionMeta info) + { + lock (_discInfoLock) + { + if (string.IsNullOrWhiteSpace(uniqueVersion)) + { + info = new BasisBEEExtensionMeta(); + return false; + } + + string platformAwarePath = BasisIOManagement.GetMetaCacheFilePath(uniqueVersion, BasisIOManagement.GetCurrentCachePlatform()); + if (TryLoadDiscInfoFromFile(platformAwarePath, expectedRemoteUrl, out info)) { - info = lazyLoadedInfo; return true; } - info = new BasisBEEExtensionMeta(); - return false; + string legacyPath = BasisIOManagement.GetLegacyMetaCacheFilePath(uniqueVersion); + return TryLoadDiscInfoFromFile(legacyPath, expectedRemoteUrl, out info); } } @@ -370,8 +368,16 @@ public static async Task EnsureInitializationComplete() private static async Task LoadAllDiscData() { BasisDebug.Log("Loading all disc data...", BasisDebug.LogTag.Event); - string path = BasisIOManagement.GenerateFolderPath(BasisBeeConstants.AssetBundlesFolder); - string[] files = Directory.GetFiles(path, $"*{BasisBeeConstants.BasisMetaExtension}"); + string rootPath = BasisIOManagement.GenerateFolderPath(BasisBeeConstants.AssetBundlesFolder); + string currentPlatformPath = BasisIOManagement.GenerateFolderPath(Path.Combine(BasisBeeConstants.AssetBundlesFolder, BasisIOManagement.GetCurrentCachePlatform())); + + List files = new List(); + files.AddRange(Directory.GetFiles(rootPath, $"*{BasisBeeConstants.BasisMetaExtension}", SearchOption.TopDirectoryOnly)); + + if (!string.Equals(rootPath, currentPlatformPath, StringComparison.OrdinalIgnoreCase) && Directory.Exists(currentPlatformPath)) + { + files.AddRange(Directory.GetFiles(currentPlatformPath, $"*{BasisBeeConstants.BasisMetaExtension}", SearchOption.TopDirectoryOnly)); + } List loadTasks = new List(); diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs index f49d5d3c73..58b977d94b 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using UnityEngine; @@ -47,11 +48,11 @@ public static long GetTotalCacheSizeBytes() return 0; long total = 0; - foreach (string file in Directory.GetFiles(folderPath)) + foreach (FieldInfo file in DirectoryInfo.GetFiles(folderPath, "*", SearchOption.AllDirectories)) { try { - total += new FileInfo(file).Length; + total += file.Length; } catch (Exception) { @@ -208,7 +209,7 @@ public static void ClearAllCache() string folderPath = GetCacheFolderPath(); if (Directory.Exists(folderPath)) { - foreach (string file in Directory.GetFiles(folderPath)) + foreach (string file in Directory.GetFiles(folderPath, "*", SearchOption.AllDirectories)) { TryDeleteFile(file); } diff --git a/Basis/Packages/com.basis.common/BasisDataStore.cs b/Basis/Packages/com.basis.common/BasisDataStore.cs index d5a9b5920e..02b70ef6e9 100644 --- a/Basis/Packages/com.basis.common/BasisDataStore.cs +++ b/Basis/Packages/com.basis.common/BasisDataStore.cs @@ -7,12 +7,12 @@ namespace Basis.Scripts.Common { public static class BasisDataStore { - public static void SaveAvatar(string avatarName, byte avatarData, string fileNameAndExtension) + public static void SaveAvatar(string avatarName, byte avatarData, string fileNameAndExtension, string cacheFileName = "") { try { string filePath = Path.Combine(Application.persistentDataPath, fileNameAndExtension); - string json = JsonUtility.ToJson(new BasisSavedAvatar(avatarName, avatarData)); + string json = JsonUtility.ToJson(new BasisSavedAvatar(avatarName, avatarData, cacheFileName)); File.WriteAllText(filePath, json); BasisDebug.Log("Avatar saved to " + filePath); } @@ -27,11 +27,13 @@ public class BasisSavedAvatar { public string UniqueID; public byte loadmode; + public string CacheFileName; - public BasisSavedAvatar(string name, byte data) + public BasisSavedAvatar(string name, byte data, string cacheFileName = "") { UniqueID = name; loadmode = data; + CacheFileName = cacheFileName; } } diff --git a/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs b/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs index 8c9ff5517b..54fa4ba505 100644 --- a/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs +++ b/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs @@ -253,7 +253,21 @@ public async Task LocalInitialize() /// Metadata pointing to the last persisted avatar selection. public async Task LoadInitialAvatar(BasisDataStore.BasisSavedAvatar LastUsedAvatar) { - if (BasisLoadHandler.IsMetaDataOnDisc(LastUsedAvatar.UniqueID, out BasisBEEExtensionMeta info)) + bool hasCachedMeta = false; + BasisBEEExtensionMeta info = null; + + if (!string.IsNullOrWhiteSpace(LastUsedAvatar.CacheFileName)) + { + hasCachedMeta = BasisLoadHandler.TryLoadMetaDataFromCacheFile(LastUsedAvatar.CacheFileName, LastUsedAvatar.UniqueID, out info); + } + + if (!hasCachedMeta) + { + await BasisLoadHandler.EnsureInitializationComplete(); + hasCachedMeta = BasisLoadHandler.IsMetaDataOnDisc(LastUsedAvatar.UniqueID, out info); + } + + if (hasCachedMeta) { await BasisDataStoreItemKeys.LoadKeys(); ItemKey[] activeKeys = BasisDataStoreItemKeys.DisplayKeys(); @@ -339,7 +353,7 @@ public async Task CreateAvatar(byte LoadMode, BasisLoadableBundle BasisLoadableB { await BasisAvatarFactory.LoadAvatarLocal(this, LoadMode, BasisLoadableBundle, this.transform.position, Quaternion.identity); OnLocalAvatarChanged?.Invoke(); - BasisDataStore.SaveAvatar(BasisLoadableBundle.BasisRemoteBundleEncrypted.RemoteBeeFileLocation, LoadMode, LoadFileNameAndExtension); + BasisDataStore.SaveAvatar(BasisLoadableBundle.BasisRemoteBundleEncrypted.RemoteBeeFileLocation, LoadMode, LoadFileNameAndExtension, BasisLoadableBundle.BasisBundleConnector?.UniqueVersion); } /// From 12740f4ffa41ae7da05d654682f3758411e548e6 Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Tue, 31 Mar 2026 02:49:16 -0500 Subject: [PATCH 5/6] Correct to proper formating for DirectoryInfo --- .../com.basis.bundlemanagement/BasisStorageManagement.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs index 58b977d94b..07100d1153 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs @@ -48,7 +48,8 @@ public static long GetTotalCacheSizeBytes() return 0; long total = 0; - foreach (FieldInfo file in DirectoryInfo.GetFiles(folderPath, "*", SearchOption.AllDirectories)) + DirectoryInfo folderInfo = new DirectoryInfo(folderPath); + foreach (FileInfo file in folderInfo.GetFiles( "*", SearchOption.AllDirectories)) { try { From 4a0bcc526c96b277db3634b86b479670b67744b9 Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Tue, 31 Mar 2026 02:54:14 -0500 Subject: [PATCH 6/6] Add legacy support for missing uniqueVersion in storage data. --- .../BasisStorageManagement.cs | 17 ++++++++++++----- .../SettingsProviderStorage.cs | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs index 07100d1153..cea59499ff 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs @@ -82,12 +82,16 @@ public static List GetAllStoredFiles() remoteUrl = meta.StoredRemote.RemoteBeeFileLocation; string beePath = meta.StoredLocal.DownloadedBeeFileLocation; - if (string.IsNullOrEmpty(beePath)) + if (string.IsNullOrEmpty(beePath) && string.IsNullOrWhiteSpace(meta.UniqueVersion) == false) { beePath = BasisIOManagement.GetBeeCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); } - string metaFilePath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); + string metaFilePath = string.Empty; + if (string.IsNullOrWhiteSpace(meta.UniqueVersion) == false) + { + metaFilePath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); + } long fileSize = 0; DateTime lastWrite = DateTime.MinValue; @@ -281,14 +285,17 @@ private static bool DeleteStoredEntry(string discKey, BasisBEEExtensionMeta meta } string beePath = meta.StoredLocal.DownloadedBeeFileLocation; - if (string.IsNullOrEmpty(beePath)) + if (string.IsNullOrEmpty(beePath) && string.IsNullOrWhiteSpace(meta.UniqueVersion) == false) { beePath = BasisIOManagement.GetBeeCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); } TryDeleteFile(beePath); - string metaPath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); - TryDeleteFile(metaPath); + if (string.IsNullOrWhiteSpace(meta.UniqueVersion) == false) + { + string metaPath = BasisIOManagement.GetMetaCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); + TryDeleteFile(metaPath); + } BasisDebug.Log($"Deleted stored BEE file: {meta.UniqueVersion} [{meta.DownloadedPlatform}] (source: {meta.StoredRemote.RemoteBeeFileLocation})", BasisDebug.LogTag.Event); return true; diff --git a/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs b/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs index a2bef94658..e7baf94139 100644 --- a/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs +++ b/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs @@ -106,7 +106,9 @@ private static void PopulateStorageData(RectTransform container) foreach (var file in storedFiles) { - string fileName = file.UniqueVersion; + string fileName = string.IsNullOrWhiteSpace(file.UniqueVersion) + ? (string.IsNullOrWhiteSpace(file.LocalPath) ? "Unknown Cache Entry" : System.IO.Path.GetFileName(file.LocalPath)) + : file.UniqueVersion; string size = BasisStorageManagement.FormatBytes(file.FileSizeBytes); string loadedStatus = file.IsLoadedInMemory ? " [IN USE]" : ""; string remoteUrl = file.RemoteUrl;