Skip to content
21 changes: 13 additions & 8 deletions Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
96 changes: 51 additions & 45 deletions Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<BasisBEEExtensionMeta>(fileData);
if (discInfo?.StoredRemote?.RemoteBeeFileLocation == null)
{
byte[] fileData = File.ReadAllBytes(file);
BasisBEEExtensionMeta discInfo = BasisSerialization.DeserializeValue<BasisBEEExtensionMeta>(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)
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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<string> files = new List<string>();
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<Task> loadTasks = new List<Task>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -80,12 +82,16 @@ public static List<StoredBeeFileInfo> 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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -279,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;
Expand Down
8 changes: 5 additions & 3 deletions Basis/Packages/com.basis.common/BasisDataStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,21 @@ public async Task LocalInitialize()
/// <param name="LastUsedAvatar">Metadata pointing to the last persisted avatar selection.</param>
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();
Expand Down Expand Up @@ -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);
}

/// <summary>
Expand Down
Loading