diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem.meta new file mode 100644 index 00000000..0ec24d20 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d2280a83472bd14bb033f506647284d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs new file mode 100644 index 00000000..bf49db77 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs @@ -0,0 +1,280 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using System; +using System.Collections.Generic; +using UnityEngine; +using YooAsset; +using AlipaySdk; + +public static class AlipayFileSystemCreater +{ + public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices) + { + string fileSystemClass = $"{nameof(AlipayFileSystem)},YooAsset.MiniGame"; + var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); + fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); + return fileSystemParams; + } + + public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices, IWebDecryptionServices decryptionServices) + { + string fileSystemClass = $"{nameof(AlipayFileSystem)},YooAsset.MiniGame"; + var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); + fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); + fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); + return fileSystemParams; + } +} + +/// +/// 支付宝小游戏文件系统 +/// 参考:https://opendocs.alipay.com/mini-game/0ftleg +/// +internal class AlipayFileSystem : IFileSystem +{ + private class WebRemoteServices : IRemoteServices + { + private readonly string _webPackageRoot; + protected readonly Dictionary _mapping = new Dictionary(10000); + + public WebRemoteServices(string buildinPackRoot) + { + _webPackageRoot = buildinPackRoot; + } + string IRemoteServices.GetRemoteMainURL(string fileName) + { + return GetFileLoadURL(fileName); + } + string IRemoteServices.GetRemoteFallbackURL(string fileName) + { + return GetFileLoadURL(fileName); + } + + private string GetFileLoadURL(string fileName) + { + if (_mapping.TryGetValue(fileName, out string url) == false) + { + string filePath = PathUtility.Combine(_webPackageRoot, fileName); + url = DownloadSystemHelper.ConvertToWWWPath(filePath); + _mapping.Add(fileName, url); + } + return url; + } + } + + private readonly Dictionary _cacheFilePathMapping = new Dictionary(10000); + private AlipayFSManager _fileSystemMgr; + private string _aliCacheRoot = string.Empty; + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _aliCacheRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + #region 自定义参数 + /// + /// 自定义参数:远程服务接口 + /// + public IRemoteServices RemoteServices { private set; get; } = null; + + /// + /// 自定义参数:解密方法类 + /// + public IWebDecryptionServices DecryptionServices { private set; get; } + + /// + /// 自定义参数:资源清单服务类 + /// + public IManifestRestoreServices ManifestServices { private set; get; } + #endregion + + + public AlipayFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new APFSInitializeOperation(this); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + { + var operation = new APFSLoadPackageManifestOperation(this, packageVersion, timeout); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new APFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + return operation; + } + public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + { + var operation = new FSClearCacheFilesCompleteOperation(); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) + { + string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); + string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); + options.SetURL(mainURL, fallbackURL); + var operation = new APFSDownloadFileOperation(this, bundle, options); + return operation; + } + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + { + var operation = new APFSLoadBundleOperation(this, bundle); + return operation; + } + else + { + string error = $"{nameof(AlipayFileSystem)} not support load bundle type : {bundle.BundleType}"; + var operation = new FSLoadBundleCompleteOperation(error); + return operation; + } + } + + public virtual void SetParameter(string name, object value) + { + if (name == FileSystemParametersDefine.REMOTE_SERVICES) + { + RemoteServices = (IRemoteServices)value; + } + else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES) + { + DecryptionServices = (IWebDecryptionServices)value; + } + else if (name == FileSystemParametersDefine.MANIFEST_SERVICES) + { + ManifestServices = (IManifestRestoreServices)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + _aliCacheRoot = rootDirectory; + + if (string.IsNullOrEmpty(_aliCacheRoot)) + { + throw new System.Exception("请配置支付宝小游戏的缓存根目录!"); + } + + // 注意:CDN服务未启用的情况下,使用支付宝WEB服务器 + if (RemoteServices == null) + { + string webRoot = PathUtility.Combine(Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName, packageName); + RemoteServices = new WebRemoteServices(webRoot); + } + + _fileSystemMgr = AlipaySDK.API.GetFileSystemManager(); + } + public virtual void OnDestroy() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + return CheckCacheFileExist(bundle); + } + public virtual bool NeedDownload(PackageBundle bundle) + { + if (Belong(bundle) == false) + return false; + + return Exists(bundle) == false; + } + public virtual bool NeedUnpack(PackageBundle bundle) + { + return false; + } + public virtual bool NeedImport(PackageBundle bundle) + { + return false; + } + + public virtual string GetBundleFilePath(PackageBundle bundle) + { + return GetCacheFileLoadPath(bundle); + } + public virtual byte[] ReadBundleFileData(PackageBundle bundle) + { + if (CheckCacheFileExist(bundle)) + { + string filePath = GetCacheFileLoadPath(bundle); + return _fileSystemMgr.ReadFileSync(filePath); + } + else + { + return Array.Empty(); + } + } + public virtual string ReadBundleFileText(PackageBundle bundle) + { + if (CheckCacheFileExist(bundle)) + { + string filePath = GetCacheFileLoadPath(bundle); + return _fileSystemMgr.ReadFileSync(filePath, "utf8"); + } + else + { + return string.Empty; + } + } + + #region 内部方法 + public AlipayFSManager GetFileSystemMgr() + { + return _fileSystemMgr; + } + public bool CheckCacheFileExist(PackageBundle bundle) + { + //TODO : 效率极低 + /* + string filePath = GetCacheFileLoadPath(bundle); + string result = _fileSystemMgr.AccessSync(filePath); + return result.Equals("access:ok", StringComparison.Ordinal); + */ + return false; + } + private string GetCacheFileLoadPath(PackageBundle bundle) + { + if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_aliCacheRoot, bundle.FileName); + _cacheFilePathMapping.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + #endregion +} +#endif diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs.meta new file mode 100644 index 00000000..ecb2e1e7 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/AlipayFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61be9965c7f7aae468a34b3ed38116b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult.meta new file mode 100644 index 00000000..9359b1d5 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44b9746ed3270394eb54d85b27a2ef04 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs new file mode 100644 index 00000000..6a53aebe --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs @@ -0,0 +1,67 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using System.IO; +using UnityEngine; +using UnityEngine.SceneManagement; +using AlipaySdk; + +namespace YooAsset +{ + internal class APAssetBundleResult : BundleResult + { + private readonly IFileSystem _fileSystem; + private readonly PackageBundle _packageBundle; + private readonly AssetBundle _assetBundle; + + public APAssetBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, AssetBundle assetBundle) + { + _fileSystem = fileSystem; + _packageBundle = packageBundle; + _assetBundle = assetBundle; + } + + public override void UnloadBundleFile() + { + if (_assetBundle != null) + { + if (_packageBundle.Encrypted) + _assetBundle.Unload(true); + else + _assetBundle.APUnload(true); + } + } + public override string GetBundleFilePath() + { + return _fileSystem.GetBundleFilePath(_packageBundle); + } + public override byte[] ReadBundleFileData() + { + return _fileSystem.ReadBundleFileData(_packageBundle); + } + public override string ReadBundleFileText() + { + return _fileSystem.ReadBundleFileText(_packageBundle); + } + + public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo) + { + var operation = new AssetBundleLoadAssetOperation(_packageBundle, _assetBundle, assetInfo); + return operation; + } + public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo) + { + var operation = new AssetBundleLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo); + return operation; + } + public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo) + { + var operation = new AssetBundleLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo); + return operation; + } + public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) + { + var operation = new AssetBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad); + return operation; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs.meta new file mode 100644 index 00000000..3cdbc4d1 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/BundleResult/APAssetBundleResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1de437726bd89584da56aaddfdb1a07c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation.meta new file mode 100644 index 00000000..46ba23ce --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 18ae5147de9585045ab40941d945696b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs new file mode 100644 index 00000000..3e49047b --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs @@ -0,0 +1,111 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using UnityEngine; +using YooAsset; + +internal class APFSDownloadFileOperation : FSDownloadFileOperation +{ + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly DownloadFileOptions _options; + private UnityWebCacheRequestOperation _webCacheRequestOp; + private int _requestCount = 0; + private float _tryAgainTimer; + private int _failedTryAgain; + private ESteps _steps = ESteps.None; + + internal APFSDownloadFileOperation(AlipayFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) + { + _fileSystem = fileSystem; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + _webCacheRequestOp = new UnityWebCacheRequestOperation(url); + _webCacheRequestOp.StartOperation(); + AddChildOperation(_webCacheRequestOp); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + _webCacheRequestOp.UpdateOperation(); + Progress = _webCacheRequestOp.Progress; + DownloadProgress = _webCacheRequestOp.DownloadProgress; + DownloadedBytes = _webCacheRequestOp.DownloadedBytes; + if (_webCacheRequestOp.IsDone == false) + return; + + if (_webCacheRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + + //TODO 需要验证插件请求器的下载进度 + DownloadProgress = 1f; + DownloadedBytes = Bundle.FileSize; + Progress = 1f; + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_webCacheRequestOp.URL} Try again !"); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webCacheRequestOp.Error; + YooLogger.Error(Error); + } + } + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 获取网络请求地址 + /// + private string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs.meta new file mode 100644 index 00000000..93a790f6 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc47317a416e9f542b7ec6b77485a8b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs new file mode 100644 index 00000000..181b87ca --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs @@ -0,0 +1,20 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal partial class APFSInitializeOperation : FSInitializeFileSystemOperation +{ + private readonly AlipayFileSystem _fileSystem; + + public APFSInitializeOperation(AlipayFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalUpdate() + { + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs.meta new file mode 100644 index 00000000..86f090da --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71a99a94d7563fe4a9d56ea0e15aa8d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs new file mode 100644 index 00000000..ca289564 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class APFSLoadBundleOperation : FSLoadBundleOperation +{ + private enum ESteps + { + None, + LoadAssetBundle, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private LoadWebAssetBundleOperation _loadWebAssetBundleOp; + private ESteps _steps = ESteps.None; + + internal APFSLoadBundleOperation(AlipayFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.LoadAssetBundle; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadAssetBundle) + { + if (_loadWebAssetBundleOp == null) + { + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); + string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); + DownloadFileOptions options = new DownloadFileOptions(int.MaxValue); + options.SetURL(mainURL, fallbackURL); + + if (_bundle.Encrypted) + { + _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices); + _loadWebAssetBundleOp.StartOperation(); + AddChildOperation(_loadWebAssetBundleOp); + } + else + { + _loadWebAssetBundleOp = new LoadAlipayAssetBundleOperation(_bundle, options); + _loadWebAssetBundleOp.StartOperation(); + AddChildOperation(_loadWebAssetBundleOp); + } + } + + _loadWebAssetBundleOp.UpdateOperation(); + Progress = _loadWebAssetBundleOp.Progress; + DownloadProgress = _loadWebAssetBundleOp.DownloadProgress; + DownloadedBytes = _loadWebAssetBundleOp.DownloadedBytes; + if (_loadWebAssetBundleOp.IsDone == false) + return; + + if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed) + { + var assetBundle = _loadWebAssetBundleOp.Result; + _steps = ESteps.Done; + Result = new APAssetBundleResult(_fileSystem, _bundle, assetBundle); + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadWebAssetBundleOp.Error; + } + } + } + internal override void InternalWaitForAsyncComplete() + { + if (_steps != ESteps.Done) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "WebGL platform not support sync load method !"; + UnityEngine.Debug.LogError(Error); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs.meta new file mode 100644 index 00000000..5b3fd077 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f71fc4fc468d41441b00be64938b2fe9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs new file mode 100644 index 00000000..4b0b3783 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs @@ -0,0 +1,92 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class APFSLoadPackageManifestOperation : FSLoadPackageManifestOperation +{ + private enum ESteps + { + None, + RequestPackageHash, + LoadPackageManifest, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private RequestAlipayPackageHashOperation _requestPackageHashOp; + private LoadAlipayPackageManifestOperation _loadPackageManifestOp; + private ESteps _steps = ESteps.None; + + + public APFSLoadPackageManifestOperation(AlipayFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalStart() + { + _steps = ESteps.RequestPackageHash; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageHash) + { + if (_requestPackageHashOp == null) + { + _requestPackageHashOp = new RequestAlipayPackageHashOperation(_fileSystem, _packageVersion, _timeout); + _requestPackageHashOp.StartOperation(); + AddChildOperation(_requestPackageHashOp); + } + + _requestPackageHashOp.UpdateOperation(); + if (_requestPackageHashOp.IsDone == false) + return; + + if (_requestPackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadPackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestPackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadPackageManifest) + { + if (_loadPackageManifestOp == null) + { + string packageHash = _requestPackageHashOp.PackageHash; + _loadPackageManifestOp = new LoadAlipayPackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout); + _loadPackageManifestOp.StartOperation(); + AddChildOperation(_loadPackageManifestOp); + } + + _loadPackageManifestOp.UpdateOperation(); + Progress = _loadPackageManifestOp.Progress; + if (_loadPackageManifestOp.IsDone == false) + return; + + if (_loadPackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _loadPackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadPackageManifestOp.Error; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 00000000..77ab0ab4 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 335885fb4e1977a4ca5c26263eda03d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs new file mode 100644 index 00000000..ba5b117f --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs @@ -0,0 +1,64 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class APFSRequestPackageVersionOperation : FSRequestPackageVersionOperation +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private RequestAlipayPackageVersionOperation _requestWebPackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal APFSRequestPackageVersionOperation(AlipayFileSystem fileSystem, bool appendTimeTicks, int timeout) + { + _fileSystem = fileSystem; + _appendTimeTicks = appendTimeTicks; + _timeout = timeout; + } + internal override void InternalStart() + { + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageVersion) + { + if (_requestWebPackageVersionOp == null) + { + _requestWebPackageVersionOp = new RequestAlipayPackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout); + _requestWebPackageVersionOp.StartOperation(); + AddChildOperation(_requestWebPackageVersionOp); + } + + _requestWebPackageVersionOp.UpdateOperation(); + Progress = _requestWebPackageVersionOp.Progress; + if (_requestWebPackageVersionOp.IsDone == false) + return; + + if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + PackageVersion = _requestWebPackageVersionOp.PackageVersion; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestWebPackageVersionOp.Error; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 00000000..cc074ca7 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/APFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a879fd6a506b37345b4b9ea6c5de20bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal.meta new file mode 100644 index 00000000..5f9812d9 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b94d7bcfa19151046a1f0ed8e089a474 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs new file mode 100644 index 00000000..8174fdf9 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs @@ -0,0 +1,115 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using UnityEngine; +using AlipaySdk; + +namespace YooAsset +{ + internal class LoadAlipayAssetBundleOperation : LoadWebAssetBundleOperation + { + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly PackageBundle _bundle; + private readonly DownloadFileOptions _options; + private UnityAlipayAssetBundleRequestOperation _unityAssetBundleRequestOp; + + private int _requestCount = 0; + private float _tryAgainTimer; + private int _failedTryAgain; + private ESteps _steps = ESteps.None; + + + internal LoadAlipayAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) + { + _bundle = bundle; + _options = options; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + _unityAssetBundleRequestOp = new UnityAlipayAssetBundleRequestOperation(_bundle, url); + _unityAssetBundleRequestOp.StartOperation(); + AddChildOperation(_unityAssetBundleRequestOp); + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + _unityAssetBundleRequestOp.UpdateOperation(); + Progress = _unityAssetBundleRequestOp.Progress; + DownloadProgress = _unityAssetBundleRequestOp.DownloadProgress; + DownloadedBytes = _unityAssetBundleRequestOp.DownloadedBytes; + if (_unityAssetBundleRequestOp.IsDone == false) + return; + + if (_unityAssetBundleRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + Result = _unityAssetBundleRequestOp.Result; + } + else + { + if (_failedTryAgain > 0) + { + _steps = ESteps.TryAgain; + YooLogger.Warning($"Failed download : {_unityAssetBundleRequestOp.URL} Try again !"); + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _unityAssetBundleRequestOp.Error; + YooLogger.Error(Error); + } + } + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + _tryAgainTimer = 0f; + _failedTryAgain--; + Progress = 0f; + DownloadProgress = 0f; + DownloadedBytes = 0; + _steps = ESteps.CreateRequest; + } + } + } + + /// + /// 获取网络请求地址 + /// + private string GetRequestURL() + { + // 轮流返回请求地址 + _requestCount++; + if (_requestCount % 2 == 0) + return _options.FallbackURL; + else + return _options.MainURL; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs.meta new file mode 100644 index 00000000..041efb4a --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayAssetBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62249d32580e2ef48a33afb58515312a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs new file mode 100644 index 00000000..de343777 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs @@ -0,0 +1,129 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class LoadAlipayPackageManifestOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly string _packageHash; + private readonly int _timeout; + private UnityWebDataRequestOperation _webDataRequestOp; + private DeserializeManifestOperation _deserializer; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹清单 + /// + public PackageManifest Manifest { private set; get; } + + + internal LoadAlipayPackageManifestOperation(AlipayFileSystem fileSystem, string packageVersion, string packageHash, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + _timeout = timeout; + } + internal override void InternalStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadAlipayPackageManifestOperation)); + _steps = ESteps.RequestFileData; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestFileData) + { + if (_webDataRequestOp == null) + { + string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion); + string url = GetRequestURL(fileName); + _webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout); + _webDataRequestOp.StartOperation(); + AddChildOperation(_webDataRequestOp); + } + + _webDataRequestOp.UpdateOperation(); + Progress = _webDataRequestOp.Progress; + if (_webDataRequestOp.IsDone == false) + return; + + if (_webDataRequestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.VerifyFileData; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webDataRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadAlipayPackageManifestOperation)); + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result); + _deserializer.StartOperation(); + AddChildOperation(_deserializer); + } + + _deserializer.UpdateOperation(); + Progress = _deserializer.Progress; + if (_deserializer.IsDone == false) + return; + + if (_deserializer.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _deserializer.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _deserializer.Error; + } + } + } + + private string GetRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs.meta new file mode 100644 index 00000000..77d0ee62 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/LoadAlipayPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c802e6ad51754e144bb4e08942da9592 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs new file mode 100644 index 00000000..617e627a --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs @@ -0,0 +1,92 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class RequestAlipayPackageHashOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹哈希值 + /// + public string PackageHash { private set; get; } + + + public RequestAlipayPackageHashOperation(AlipayFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestAlipayPackageHashOperation)); + _steps = ESteps.RequestPackageHash; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageHash) + { + if (_webTextRequestOp == null) + { + string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion); + string url = GetRequestURL(fileName); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + _webTextRequestOp.StartOperation(); + AddChildOperation(_webTextRequestOp); + } + + _webTextRequestOp.UpdateOperation(); + Progress = _webTextRequestOp.Progress; + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status == EOperationStatus.Succeed) + { + PackageHash = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageHash)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Web package hash file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestAlipayPackageHashOperation)); + } + } + } + + private string GetRequestURL(string fileName) + { + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + return _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs.meta new file mode 100644 index 00000000..9559c2a2 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b4f8cf6fe34a7e419f8e3a0063f591b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs new file mode 100644 index 00000000..69874c5b --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs @@ -0,0 +1,100 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using YooAsset; + +internal class RequestAlipayPackageVersionOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly AlipayFileSystem _fileSystem; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹版本 + /// + public string PackageVersion { private set; get; } + + + public RequestAlipayPackageVersionOperation(AlipayFileSystem fileSystem, bool appendTimeTicks, int timeout) + { + _fileSystem = fileSystem; + _appendTimeTicks = appendTimeTicks; + _timeout = timeout; + } + internal override void InternalStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestAlipayPackageVersionOperation)); + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageVersion) + { + if (_webTextRequestOp == null) + { + string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName); + string url = GetRequestURL(fileName); + _webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout); + _webTextRequestOp.StartOperation(); + AddChildOperation(_webTextRequestOp); + } + + _webTextRequestOp.UpdateOperation(); + Progress = _webTextRequestOp.Progress; + if (_webTextRequestOp.IsDone == false) + return; + + if (_webTextRequestOp.Status == EOperationStatus.Succeed) + { + PackageVersion = _webTextRequestOp.Result; + if (string.IsNullOrEmpty(PackageVersion)) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Web package version file content is empty !"; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _webTextRequestOp.Error; + WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestAlipayPackageVersionOperation)); + } + } + } + + private string GetRequestURL(string fileName) + { + string url; + + // 轮流返回请求地址 + if (_requestCount % 2 == 0) + url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName); + else + url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName); + + // 在URL末尾添加时间戳 + if (_appendTimeTicks) + return $"{url}?{System.DateTime.UtcNow.Ticks}"; + else + return url; + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs.meta new file mode 100644 index 00000000..08ed6918 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/RequestAlipayPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ef3d88ce51a6fa47be1b157316a740c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs new file mode 100644 index 00000000..867b79a1 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs @@ -0,0 +1,95 @@ +#if UNITY_WEBGL && UNITY_ALIMINIGAME +using UnityEngine.Networking; +using UnityEngine; +using AlipaySdk; + +namespace YooAsset +{ + internal class UnityAlipayAssetBundleRequestOperation : UnityWebRequestOperation + { + protected enum ESteps + { + None, + CreateRequest, + Download, + Done, + } + + private readonly PackageBundle _packageBundle; + private UnityWebRequestAsyncOperation _requestOperation; + private ESteps _steps = ESteps.None; + + /// + /// 请求结果 + /// + public AssetBundle Result { private set; get; } + + internal UnityAlipayAssetBundleRequestOperation(PackageBundle bundle, string url) : base(url) + { + _packageBundle = bundle; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.CreateRequest) + { + CreateWebRequest(); + _steps = ESteps.Download; + } + + if (_steps == ESteps.Download) + { + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + Progress = _requestOperation.progress; + if (_requestOperation.isDone == false) + return; + + if (CheckRequestResult()) + { + var downloadHanlder = (DownloadHandlerAPAssetBundle)_webRequest.downloadHandler; + AssetBundle assetBundle = downloadHanlder.assetBundle; + if (assetBundle == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"URL : {_requestURL} Download handler asset bundle object is null !"; + } + else + { + _steps = ESteps.Done; + Result = assetBundle; + Status = EOperationStatus.Succeed; + + //TODO 需要验证插件请求器的下载进度 + DownloadProgress = 1f; + DownloadedBytes = _packageBundle.FileSize; + Progress = 1f; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + + // 注意:最终释放请求器 + DisposeRequest(); + } + } + + private void CreateWebRequest() + { + _webRequest = APAssetBundle.GetAssetBundle(_requestURL); + _webRequest.disposeDownloadHandlerOnDispose = true; + _requestOperation = _webRequest.SendWebRequest(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs.meta b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs.meta new file mode 100644 index 00000000..a64ab9f5 --- /dev/null +++ b/Assets/YooAsset/Samples~/Mini Game/Runtime/AlipayFileSystem/Operation/internal/UnityAlipayAssetBundleRequestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2e7a4e37ac067f4ba0a43ebea0aa3f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: