diff --git a/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs b/Basis/Packages/com.basis.bundlemanagement/BasisBEEExtensionMeta.cs
index 4217be46c..0f0b556a8 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 8597c0753..313b9eac2 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) &&
+ BasisIOManagement.CachePlatformMatchesCurrent(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 386e6eb4f..86e5e5c66 100644
--- a/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs
+++ b/Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs
@@ -7,6 +7,77 @@
public static class BasisIOManagement
{
+ public static string GetCurrentCachePlatform()
+ {
+ 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)
+ {
+ 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()
+ : NormalizeCachePlatformName(downloadedPlatform);
+
+ foreach (char invalidChar in Path.GetInvalidFileNameChars())
+ {
+ normalizedPlatform = normalizedPlatform.Replace(invalidChar, '_');
+ }
+
+ return $"{uniqueVersion}.{normalizedPlatform}{extension}";
+ }
+
public sealed class BeeDownloadResult
{
public BasisBundleConnector Connector { get; }
@@ -156,14 +227,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 +298,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 f59f47b94..7fe2b6fc2 100644
--- a/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs
+++ b/Basis/Packages/com.basis.bundlemanagement/BasisLoadhandler.cs
@@ -167,39 +167,146 @@ 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;
+ }
+
+ 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)
{
+ 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) &&
+ !BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform))
{
- 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 (BasisIOManagement.CachePlatformMatchesCurrent(discInfo.DownloadedPlatform))
{
+ info = discInfo;
return true;
}
+
+ legacyCandidate = discInfo;
}
}
}
+ if (legacyCandidate != null)
+ {
+ info = legacyCandidate;
+ return true;
+ }
+
+ if (TryLazyLoadDiscInfo(MetaURL, currentPlatform, out BasisBEEExtensionMeta lazyLoadedInfo))
+ {
+ info = lazyLoadedInfo;
+ return true;
+ }
+
info = new BasisBEEExtensionMeta();
return false;
}
@@ -207,19 +314,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);
@@ -238,7 +347,7 @@ public static void RemoveDiscInfo(string metaUrl)
BasisStorageManagement.DeleteStoredFile(metaUrl);
}
- private static async Task EnsureInitializationComplete()
+ public static async Task EnsureInitializationComplete()
{
if (!IsInitialized)
{
@@ -275,7 +384,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 +401,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 d7de86b5c..f49d5d3c7 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))
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 8bb5cd059..b9a6205a4 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 ea6934173..78122fa63 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);