Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
45 changes: 41 additions & 4 deletions Basis/Packages/com.basis.bundlemanagement/BasisBeeManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/// <summary>
/// this allows obtaining the entire bee file
/// </summary>
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this cause a feedback loop of no bad bundle -> download -> attempt bad bundle -> download repeating

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next check of didForceRedownload is the check flag so it only does it once per invocation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only thing we could do is either delete the bad local file, and return an error about the download being bad.

{
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)
{
Expand All @@ -76,7 +111,7 @@ public static async Task HandleBundleAndMetaLoading(BasisTrackedBundleWrapper wr
/// <summary>
/// Saves or updates on-disc metadata when it is missing or was refreshed by a forced re-download.
/// </summary>
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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -124,6 +160,7 @@ public static async Task<bool> HandleMetaOnlyLoad(BasisTrackedBundleWrapper wrap
StoredRemote = wrapper.LoadableBundle.BasisRemoteBundleEncrypted,
StoredLocal = wrapper.LoadableBundle.BasisLocalEncryptedBundle,
UniqueVersion = wrapper.LoadableBundle.BasisBundleConnector.UniqueVersion,
DownloadedPlatform = BasisIOManagement.GetCurrentCachePlatform(),
};

await BasisLoadHandler.AddDiscInfo(newDiscInfo);
Expand Down
79 changes: 75 additions & 4 deletions Basis/Packages/com.basis.bundlemanagement/BasisIOManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -156,14 +227,14 @@ public static async Task<BeeResult<BeeDownloadResult>> 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<BeeDownloadResult>.Fail("DownloadBEEEx: Connector has no UniqueVersion / file extension.");

string localPath;
try
{
localPath = GenerateFilePath(fileName, BasisBeeConstants.AssetBundlesFolder);
localPath = GetBeeCacheFilePath(connector.UniqueVersion);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -227,13 +298,13 @@ public static async Task<BeeResult<BeeDownloadResult>> 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);
Expand Down
Loading
Loading