diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs index 3ec4a5d33..965f61260 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs @@ -43,17 +43,17 @@ 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 GetConnectorCacheFilePath(string uniqueVersion, string downloadedPlatform = null) { - return GenerateFilePath(BuildPlatformAwareCacheFileName(uniqueVersion, BasisBeeConstants.BasisConnectorExtension, downloadedPlatform), BasisBeeConstants.AssetBundlesFolder); + return GenerateFilePath(BuildLegacyCacheFileName(uniqueVersion, BasisBeeConstants.BasisConnectorExtension), 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) @@ -66,21 +66,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 0bec91cc2..57e2de473 100644 --- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs +++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs @@ -213,6 +213,13 @@ private static bool TryResolveStoredBeePath(BasisBEEExtensionMeta discInfo, out string legacyPath = BasisIOManagement.GetLegacyBeeCacheFilePath(discInfo.UniqueVersion); if (File.Exists(legacyPath)) { + if (TryMigrateFile(legacyPath, platformAwarePath)) + { + discInfo.StoredLocal.DownloadedBeeFileLocation = platformAwarePath; + beePath = platformAwarePath; + return true; + } + discInfo.StoredLocal.DownloadedBeeFileLocation = legacyPath; beePath = legacyPath; return true; @@ -223,6 +230,35 @@ private static bool TryResolveStoredBeePath(BasisBEEExtensionMeta discInfo, out return false; } + private static bool TryMigrateFile(string legacyPath, string platformAwarePath) + { + if (string.Equals(legacyPath, platformAwarePath, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + try + { + string targetDir = Path.GetDirectoryName(platformAwarePath); + if (!string.IsNullOrEmpty(targetDir) && !Directory.Exists(targetDir)) + { + Directory.CreateDirectory(targetDir); + } + File.Move(legacyPath, platformAwarePath); + BasisDebug.Log($"Migrated legacy cache file: {legacyPath} -> {platformAwarePath}", BasisDebug.LogTag.Event); + return true; + } + catch (Exception ex) + { + if (File.Exists(platformAwarePath)) + { + return true; + } + BasisDebug.LogWarning($"Failed migrating legacy cache file {legacyPath} -> {platformAwarePath}: {ex.Message}", BasisDebug.LogTag.Event); + return false; + } + } + private static bool TryResolveStoredConnectorPath(BasisBEEExtensionMeta discInfo, out string connectorPath) { connectorPath = discInfo.StoredLocal.DownloadedConnectorFileLocation; @@ -251,67 +287,49 @@ private static bool HasAnyCachedPayload(BasisBEEExtensionMeta discInfo) return TryResolveStoredBeePath(discInfo, out _) || TryResolveStoredConnectorPath(discInfo, out _); } - 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 (!HasAnyCachedPayload(discInfo)) - { - 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 (!HasAnyCachedPayload(discInfo)) { - 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) { lock (_discInfoLock) { - string currentPlatform = BasisIOManagement.GetCurrentCachePlatform(); BasisBEEExtensionMeta legacyCandidate = null; foreach (var discInfo in OnDiscData.Values) @@ -343,14 +361,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); } } @@ -412,8 +445,18 @@ 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())); + + string[] legacyFiles = Directory.GetFiles(rootPath, $"*{BasisBeeConstants.BasisMetaExtension}", SearchOption.TopDirectoryOnly); + bool hasLegacy = legacyFiles.Length > 0; + + List files = new List(legacyFiles); + + if (!string.Equals(rootPath, currentPlatformPath, StringComparison.OrdinalIgnoreCase) && Directory.Exists(currentPlatformPath)) + { + files.AddRange(Directory.GetFiles(currentPlatformPath, $"*{BasisBeeConstants.BasisMetaExtension}", SearchOption.TopDirectoryOnly)); + } List loadTasks = new List(); @@ -421,26 +464,161 @@ private static async Task LoadAllDiscData() { loadTasks.Add(Task.Run(async () => { - // BasisDebug.Log($"Loading file: {file}"); + byte[] fileData; try { - byte[] fileData = await File.ReadAllBytesAsync(file); - BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); - OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; + fileData = await File.ReadAllBytesAsync(file); + } + catch (Exception ex) + { + BasisDebug.LogError($"Failed to read disc info from {file}: {ex.Message}", BasisDebug.LogTag.Event); + return; + } + + BasisBEEExtensionMeta discInfo; + try + { + discInfo = BasisSerialization.DeserializeValue(fileData); } catch (Exception ex) { - BasisDebug.LogError($"Failed to load disc info from {file}: {ex.Message}", BasisDebug.LogTag.Event); - File.Delete(file); + BasisDebug.LogError($"Corrupt disc info at {file}, deleting: {ex.Message}", BasisDebug.LogTag.Event); + try { File.Delete(file); } catch { } + return; + } + + if (discInfo?.StoredRemote?.RemoteBeeFileLocation == null) + { + BasisDebug.LogWarning($"Skipping disc info with no remote URL at {file}", BasisDebug.LogTag.Event); + return; } + + OnDiscData[GetDiscInfoKey(discInfo.StoredRemote.RemoteBeeFileLocation, discInfo.DownloadedPlatform)] = discInfo; })); } await Task.WhenAll(loadTasks); + if (hasLegacy) + { + foreach (string file in legacyFiles) + { + if (!File.Exists(file)) + { + continue; + } + + try + { + byte[] fileData = File.ReadAllBytes(file); + BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue(fileData); + if (string.IsNullOrWhiteSpace(discInfo.UniqueVersion)) + { + continue; + } + + string canonicalMetaPath = BasisIOManagement.GetMetaCacheFilePath(discInfo.UniqueVersion, discInfo.DownloadedPlatform); + if (!string.Equals(file, canonicalMetaPath, StringComparison.OrdinalIgnoreCase) && !File.Exists(canonicalMetaPath)) + { + TryMigrateFile(file, canonicalMetaPath); + } + } + catch (Exception ex) + { + BasisDebug.LogWarning($"Failed migrating legacy meta {file}: {ex.Message}", BasisDebug.LogTag.Event); + } + } + } + + MigrateLegacyPayloadFiles(rootPath, BasisBeeConstants.BasisEncryptedExtension); + MigrateLegacyPayloadFiles(rootPath, BasisBeeConstants.BasisConnectorExtension); + BasisDebug.Log("Completed loading all disc data."); } + private static readonly HashSet KnownCachePlatforms = BuildKnownCachePlatforms(); + + private static HashSet BuildKnownCachePlatforms() + { + HashSet set = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (string name in Enum.GetNames(typeof(RuntimePlatform))) + { + set.Add(name); + set.Add(BasisIOManagement.NormalizeCachePlatformName(name)); + } + set.Remove(string.Empty); + return set; + } + + private static bool TryParsePlatformSuffix(string fileNameNoExt, out string uniqueVersion, out string platform) + { + int lastDot = fileNameNoExt.LastIndexOf('.'); + if (lastDot > 0) + { + string suffix = fileNameNoExt.Substring(lastDot + 1); + if (KnownCachePlatforms.Contains(suffix)) + { + uniqueVersion = fileNameNoExt.Substring(0, lastDot); + platform = BasisIOManagement.NormalizeCachePlatformName(suffix); + if (string.IsNullOrEmpty(platform)) + { + platform = suffix; + } + return true; + } + } + + uniqueVersion = fileNameNoExt; + platform = null; + return false; + } + + private static void MigrateLegacyPayloadFiles(string rootPath, string extension) + { + string[] files = Directory.GetFiles(rootPath, $"*{extension}", SearchOption.TopDirectoryOnly); + if (files.Length == 0) + { + return; + } + + Dictionary versionToPlatform = new Dictionary(OnDiscData.Count, StringComparer.OrdinalIgnoreCase); + foreach (var meta in OnDiscData.Values) + { + if (!string.IsNullOrWhiteSpace(meta.UniqueVersion) && !string.IsNullOrWhiteSpace(meta.DownloadedPlatform)) + { + versionToPlatform[meta.UniqueVersion] = BasisIOManagement.NormalizeCachePlatformName(meta.DownloadedPlatform); + } + } + + string fallbackPlatform = BasisIOManagement.GetCurrentCachePlatform(); + + foreach (string file in files) + { + try + { + string nameNoExt = Path.GetFileNameWithoutExtension(file); + + if (!TryParsePlatformSuffix(nameNoExt, out string uniqueVersion, out string platform)) + { + if (!versionToPlatform.TryGetValue(uniqueVersion, out platform) || string.IsNullOrEmpty(platform)) + { + platform = fallbackPlatform; + } + } + + string targetPath = Path.Combine(rootPath, platform, uniqueVersion + extension); + if (!string.Equals(file, targetPath, StringComparison.OrdinalIgnoreCase) && !File.Exists(targetPath)) + { + TryMigrateFile(file, targetPath); + } + } + catch (Exception ex) + { + BasisDebug.LogWarning($"Failed migrating root payload file {file}: {ex.Message}", BasisDebug.LogTag.Event); + } + } + } + private static void CleanupFiles(BasisStoredEncryptedBundle bundle) { if (!string.IsNullOrWhiteSpace(bundle?.DownloadedBeeFileLocation) && File.Exists(bundle.DownloadedBeeFileLocation)) diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs b/Basis/Packages/com.basis.bundlemanagement/BasisStorageManagement.cs index 7dd2f57ab..728af1993 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,12 @@ public static long GetTotalCacheSizeBytes() return 0; long total = 0; - foreach (string file in Directory.GetFiles(folderPath)) + DirectoryInfo folderInfo = new DirectoryInfo(folderPath); + foreach (FileInfo file in folderInfo.GetFiles( "*", SearchOption.AllDirectories)) { try { - total += new FileInfo(file).Length; + total += file.Length; } catch (Exception) { @@ -80,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; @@ -208,7 +214,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); } @@ -279,21 +285,24 @@ 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 connectorPath = meta.StoredLocal.DownloadedConnectorFileLocation; - if (string.IsNullOrEmpty(connectorPath)) + if (string.IsNullOrEmpty(connectorPath) && string.IsNullOrWhiteSpace(meta.UniqueVersion) == false) { connectorPath = BasisIOManagement.GetConnectorCacheFilePath(meta.UniqueVersion, meta.DownloadedPlatform); } TryDeleteFile(connectorPath); - 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.common/BasisDataStore.cs b/Basis/Packages/com.basis.common/BasisDataStore.cs index d5a9b5920..02b70ef6e 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/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs b/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs index a291ea773..4da7ab8ab 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 @@ -129,7 +129,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; diff --git a/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs b/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs index aaf44475b..210644fd4 100644 --- a/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs +++ b/Basis/Packages/com.basis.framework/Players/Local/BasisLocalPlayer.cs @@ -255,7 +255,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(); @@ -341,7 +355,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); } ///