diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.cs deleted file mode 100644 index 9819578..0000000 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.cs +++ /dev/null @@ -1,296 +0,0 @@ -#if UNITY_WECHAT_GAME -using System; -using System.IO; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Networking; -using YooAsset; -using WeChatWASM; - -public static class WechatFileSystemCreater -{ - public static FileSystemParameters CreateWechatFileSystemParameters(IRemoteServices remoteServices) - { - string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension"; - var fileSystemParams = new FileSystemParameters(fileSystemClass, null); - fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); - fileSystemParams.AddParameter("DISABLE_UNITY_WEB_CACHE", true); - fileSystemParams.AddParameter("ALLOW_CROSS_ACCESS", true); - return fileSystemParams; - } -} - -/// -/// 微信小游戏文件系统扩展 -/// 参考:https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/Design/UsingAssetBundle.html -/// -internal partial class WechatFileSystem : DefaultWebFileSystem -{ - private WXFileSystemManager _wxFileSystemMgr; - private readonly Dictionary _wxFilePaths = new Dictionary(10000); - private string _wxFileCacheRoot = string.Empty; - - public override void OnCreate(string packageName, string rootDirectory) - { - base.OnCreate(packageName, rootDirectory); - - _wxFileSystemMgr = WX.GetFileSystemManager(); - _wxFileCacheRoot = WX.env.USER_DATA_PATH; //注意:如果有子目录,请修改此处! - } - - /// - /// 重写资源文件下载方法 - /// - public override FSDownloadFileOperation DownloadFileAsync(params object[] args) - { - PackageBundle bundle = args[0] as PackageBundle; - int failedTryAgain = (int)args[2]; - int timeout = (int)args[3]; - - string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); - string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); - var operation = new WechatDownloadFileOperation(this, bundle, mainURL, fallbackURL, failedTryAgain, timeout); - OperationSystem.StartOperation(PackageName, operation); - return operation; - } - - /// - /// 重写资源文件加载方法 - /// - public override FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) - { - var operation = new WechatLoadBundleOperation(this, bundle); - OperationSystem.StartOperation(PackageName, operation); - return operation; - } - - /// - /// 重写资源文件卸载方法 - /// - public override void UnloadBundleFile(PackageBundle bundle, object result) - { - AssetBundle assetBundle = result as AssetBundle; - if (assetBundle != null) - assetBundle.WXUnload(true); - } - - /// - /// 重写查询方法 - /// - public override bool Exists(PackageBundle bundle) - { - string filePath = GetWXFileLoadPath(bundle); - string result = _wxFileSystemMgr.AccessSync(filePath); - return result.Equals("access:ok"); - } - - #region 内部方法 - private string GetWXFileLoadPath(PackageBundle bundle) - { - if (_wxFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) - { - filePath = PathUtility.Combine(_wxFileCacheRoot, bundle.FileName); - _wxFilePaths.Add(bundle.BundleGUID, filePath); - } - return filePath; - } - #endregion -} - -internal partial class WechatFileSystem -{ - internal class WechatLoadBundleOperation : FSLoadBundleOperation - { - private enum ESteps - { - None, - LoadBundleFile, - Done, - } - - private readonly WechatFileSystem _fileSystem; - private readonly PackageBundle _bundle; - private UnityWebRequest _webRequest; - private ESteps _steps = ESteps.None; - - internal WechatLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle) - { - _fileSystem = fileSystem; - _bundle = bundle; - } - internal override void InternalOnStart() - { - _steps = ESteps.LoadBundleFile; - } - internal override void InternalOnUpdate() - { - if (_steps == ESteps.None || _steps == ESteps.Done) - return; - - if (_steps == ESteps.LoadBundleFile) - { - if (_webRequest == null) - { - string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); - _webRequest = WXAssetBundle.GetAssetBundle(mainURL); - _webRequest.SendWebRequest(); - } - - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = (long)_webRequest.downloadedBytes; - Progress = DownloadProgress; - if (_webRequest.isDone == false) - return; - - if (CheckRequestResult()) - { - _steps = ESteps.Done; - Result = (_webRequest.downloadHandler as DownloadHandlerWXAssetBundle).assetBundle; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - } - } - } - - public override void WaitForAsyncComplete() - { - if (IsDone == false) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - Error = "WebGL platform not support sync load method !"; - UnityEngine.Debug.LogError(Error); - } - } - public override void AbortDownloadOperation() - { - } - - private bool CheckRequestResult() - { -#if UNITY_2020_3_OR_NEWER - if (_webRequest.result != UnityWebRequest.Result.Success) - { - Error = _webRequest.error; - return false; - } - else - { - return true; - } -#else - if (_webRequest.isNetworkError || _webRequest.isHttpError) - { - Error = _webRequest.error; - return false; - } - else - { - return true; - } -#endif - } - } - internal class WechatDownloadFileOperation : DefaultDownloadFileOperation - { - private WechatFileSystem _fileSystem; - private ESteps _steps = ESteps.None; - - internal WechatDownloadFileOperation(WechatFileSystem fileSystem, PackageBundle bundle, - string mainURL, string fallbackURL, int failedTryAgain, int timeout) - : base(bundle, mainURL, fallbackURL, failedTryAgain, timeout) - { - _fileSystem = fileSystem; - } - internal override void InternalOnStart() - { - _steps = ESteps.CreateRequest; - } - internal override void InternalOnUpdate() - { - // 创建下载器 - if (_steps == ESteps.CreateRequest) - { - // 获取请求地址 - _requestURL = GetRequestURL(); - - // 重置变量 - ResetRequestFiled(); - - // 创建下载器 - CreateWebRequest(); - - _steps = ESteps.CheckRequest; - } - - // 检测下载结果 - if (_steps == ESteps.CheckRequest) - { - DownloadProgress = _webRequest.downloadProgress; - DownloadedBytes = (long)_webRequest.downloadedBytes; - Progress = DownloadProgress; - if (_webRequest.isDone == false) - { - CheckRequestTimeout(); - return; - } - - // 检查网络错误 - if (CheckRequestResult()) - { - _steps = ESteps.Done; - Status = EOperationStatus.Succeed; - } - else - { - _steps = ESteps.TryAgain; - } - - // 注意:最终释放请求器 - DisposeWebRequest(); - } - - // 重新尝试下载 - if (_steps == ESteps.TryAgain) - { - if (FailedTryAgain <= 0) - { - Status = EOperationStatus.Failed; - _steps = ESteps.Done; - YooLogger.Error(Error); - return; - } - - _tryAgainTimer += Time.unscaledDeltaTime; - if (_tryAgainTimer > 1f) - { - FailedTryAgain--; - _steps = ESteps.CreateRequest; - YooLogger.Warning(Error); - } - } - } - - private void CreateWebRequest() - { - _webRequest = WXAssetBundle.GetAssetBundle(_requestURL); - _webRequest.SetRequestHeader("wechatminigame-preload", "1"); - _webRequest.disposeDownloadHandlerOnDispose = true; - _webRequest.SendWebRequest(); - } - private void DisposeWebRequest() - { - if (_webRequest != null) - { - //注意:引擎底层会自动调用Abort方法 - _webRequest.Dispose(); - _webRequest = null; - } - } - } -} -#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.meta new file mode 100644 index 0000000..6d94b25 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f0165bf1a62988a439ce3a00db043620 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation.meta new file mode 100644 index 0000000..491fb2c --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 85ec3f4c43303f74a9b9fa14288f9201 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs new file mode 100644 index 0000000..5267d6c --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs @@ -0,0 +1,102 @@ +#if UNITY_WECHAT_GAME +using UnityEngine; +using UnityEngine.Networking; +using YooAsset; +using WeChatWASM; + +internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation +{ + private WechatFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + internal WXFSDownloadFileOperation(WechatFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalOnUpdate() + { + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + // 获取请求地址 + _requestURL = GetRequestURL(); + + // 重置变量 + ResetRequestFiled(); + + // 创建下载器 + CreateWebRequest(); + + _steps = ESteps.CheckRequest; + } + + // 检测下载结果 + if (_steps == ESteps.CheckRequest) + { + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + Progress = DownloadProgress; + if (_webRequest.isDone == false) + { + CheckRequestTimeout(); + return; + } + + // 检查网络错误 + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.TryAgain; + } + + // 注意:最终释放请求器 + DisposeWebRequest(); + } + + // 重新尝试下载 + if (_steps == ESteps.TryAgain) + { + if (FailedTryAgain <= 0) + { + Status = EOperationStatus.Failed; + _steps = ESteps.Done; + YooLogger.Error(Error); + return; + } + + _tryAgainTimer += Time.unscaledDeltaTime; + if (_tryAgainTimer > 1f) + { + FailedTryAgain--; + _steps = ESteps.CreateRequest; + YooLogger.Warning(Error); + } + } + } + + private void CreateWebRequest() + { + _webRequest = WXAssetBundle.GetAssetBundle(_requestURL); + _webRequest.SetRequestHeader("wechatminigame-preload", "1"); + _webRequest.disposeDownloadHandlerOnDispose = true; + _webRequest.SendWebRequest(); + } + private void DisposeWebRequest() + { + if (_webRequest != null) + { + //注意:引擎底层会自动调用Abort方法 + _webRequest.Dispose(); + _webRequest = null; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta new file mode 100644 index 0000000..19b0ba9 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e58c7876bd106e04380cbf4c00e8d584 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs new file mode 100644 index 0000000..45f88f7 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs @@ -0,0 +1,20 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation +{ + private readonly WechatFileSystem _fileSystem; + + public WXFSInitializeOperation(WechatFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalOnStart() + { + Status = EOperationStatus.Succeed; + } + internal override void InternalOnUpdate() + { + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta new file mode 100644 index 0000000..77e5e65 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0c5566de97a44245b840bf388cdfbe0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs new file mode 100644 index 0000000..76c2bc4 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs @@ -0,0 +1,103 @@ +#if UNITY_WECHAT_GAME +using UnityEngine; +using UnityEngine.Networking; +using YooAsset; +using WeChatWASM; + +internal class WXFSLoadBundleOperation : FSLoadBundleOperation +{ + private enum ESteps + { + None, + LoadBundleFile, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private UnityWebRequest _webRequest; + private ESteps _steps = ESteps.None; + + internal WXFSLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle) + { + _fileSystem = fileSystem; + _bundle = bundle; + } + internal override void InternalOnStart() + { + _steps = ESteps.LoadBundleFile; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.LoadBundleFile) + { + if (_webRequest == null) + { + string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); + _webRequest = WXAssetBundle.GetAssetBundle(mainURL); + _webRequest.SendWebRequest(); + } + + DownloadProgress = _webRequest.downloadProgress; + DownloadedBytes = (long)_webRequest.downloadedBytes; + Progress = DownloadProgress; + if (_webRequest.isDone == false) + return; + + if (CheckRequestResult()) + { + _steps = ESteps.Done; + Result = (_webRequest.downloadHandler as DownloadHandlerWXAssetBundle).assetBundle; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + } + } + + public override void WaitForAsyncComplete() + { + if (IsDone == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "WebGL platform not support sync load method !"; + UnityEngine.Debug.LogError(Error); + } + } + public override void AbortDownloadOperation() + { + } + + private bool CheckRequestResult() + { +#if UNITY_2020_3_OR_NEWER + if (_webRequest.result != UnityWebRequest.Result.Success) + { + Error = _webRequest.error; + return false; + } + else + { + return true; + } +#else + if (_webRequest.isNetworkError || _webRequest.isHttpError) + { + Error = _webRequest.error; + return false; + } + else + { + return true; + } +#endif + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta new file mode 100644 index 0000000..04eec17 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7277b7d1ed5616b41986cad60c3fe97c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs new file mode 100644 index 0000000..0bf30d9 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal class WXFSLoadPackageManifestOperation : FSLoadPackageManifestOperation +{ + private enum ESteps + { + None, + RequestRemotePackageHash, + LoadRemotePackageManifest, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private RequestWechatPackageHashOperation _requestRemotePackageHashOp; + private LoadWechatPackageManifestOperation _loadRemotePackageManifestOp; + private ESteps _steps = ESteps.None; + + + public WXFSLoadPackageManifestOperation(WechatFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestRemotePackageHash; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestRemotePackageHash) + { + if (_requestRemotePackageHashOp == null) + { + _requestRemotePackageHashOp = new RequestWechatPackageHashOperation(_fileSystem, _packageVersion, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestRemotePackageHashOp); + } + + if (_requestRemotePackageHashOp.IsDone == false) + return; + + if (_requestRemotePackageHashOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.LoadRemotePackageManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _requestRemotePackageHashOp.Error; + } + } + + if (_steps == ESteps.LoadRemotePackageManifest) + { + if (_loadRemotePackageManifestOp == null) + { + string packageHash = _requestRemotePackageHashOp.PackageHash; + _loadRemotePackageManifestOp = new LoadWechatPackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _loadRemotePackageManifestOp); + } + + Progress = _loadRemotePackageManifestOp.Progress; + if (_loadRemotePackageManifestOp.IsDone == false) + return; + + if (_loadRemotePackageManifestOp.Status == EOperationStatus.Succeed) + { + _steps = ESteps.Done; + Manifest = _loadRemotePackageManifestOp.Manifest; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = _loadRemotePackageManifestOp.Error; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 0000000..bb1d302 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cfbe2efa84cb0524f9e3482e6b895f41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs new file mode 100644 index 0000000..20932e0 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs @@ -0,0 +1,60 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal class WXFSRequestPackageVersionOperation : FSRequestPackageVersionOperation +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly int _timeout; + private RequestWechatPackageVersionOperation _requestWebPackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal WXFSRequestPackageVersionOperation(WechatFileSystem fileSystem, int timeout) + { + _fileSystem = fileSystem; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalOnUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.RequestPackageVersion) + { + if (_requestWebPackageVersionOp == null) + { + _requestWebPackageVersionOp = new RequestWechatPackageVersionOperation(_fileSystem, _timeout); + OperationSystem.StartOperation(_fileSystem.PackageName, _requestWebPackageVersionOp); + } + + 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~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 0000000..d71d9a1 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4353a9a0cbf86cc43acf3320458e3ac8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal.meta new file mode 100644 index 0000000..cf76301 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3fd307b5063003545a663ccbec226a23 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs new file mode 100644 index 0000000..74aebfe --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs @@ -0,0 +1,125 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal class LoadWechatPackageManifestOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly WechatFileSystem _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 LoadWechatPackageManifestOperation(WechatFileSystem fileSystem, string packageVersion, string packageHash, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _packageHash = packageHash; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadWechatPackageManifestOperation)); + _steps = ESteps.RequestFileData; + } + internal override void InternalOnUpdate() + { + 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); + OperationSystem.StartOperation(_fileSystem.PackageName, _webDataRequestOp); + } + + 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(LoadWechatPackageManifestOperation)); + } + } + + if (_steps == ESteps.VerifyFileData) + { + string fileHash = HashUtility.BytesMD5(_webDataRequestOp.Result); + if (fileHash == _packageHash) + { + _steps = ESteps.LoadManifest; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Failed to verify wechat package manifest file!"; + } + } + + if (_steps == ESteps.LoadManifest) + { + if (_deserializer == null) + { + _deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); + OperationSystem.StartOperation(_fileSystem.PackageName, _deserializer); + } + + 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~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs.meta new file mode 100644 index 0000000..183900f --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/LoadWechatPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c2153284d246964fb2146f9fdda311c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs new file mode 100644 index 0000000..debc013 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs @@ -0,0 +1,90 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal class RequestWechatPackageHashOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly WechatFileSystem _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 RequestWechatPackageHashOperation(WechatFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWechatPackageHashOperation)); + _steps = ESteps.RequestPackageHash; + } + internal override void InternalOnUpdate() + { + 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); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + 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 = $"Wechat 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(RequestWechatPackageHashOperation)); + } + } + } + + 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~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs.meta new file mode 100644 index 0000000..c2f4ed9 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f8269507a575884f935f9fbc71396ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs new file mode 100644 index 0000000..f0260ac --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WECHAT_GAME +using YooAsset; + +internal class RequestWechatPackageVersionOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹版本 + /// + public string PackageVersion { private set; get; } + + + public RequestWechatPackageVersionOperation(WechatFileSystem fileSystem, int timeout) + { + _fileSystem = fileSystem; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWechatPackageVersionOperation)); + _steps = ESteps.RequestPackageVersion; + } + internal override void InternalOnUpdate() + { + 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); + OperationSystem.StartOperation(_fileSystem.PackageName, _webTextRequestOp); + } + + 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 = $"Wechat 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(RequestWechatPackageVersionOperation)); + } + } + } + + 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~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs.meta new file mode 100644 index 0000000..8958ebe --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/Operation/internal/RequestWechatPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 758fbcd91469b3f4e843a9ea7e3deda9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/WechatFileSystem.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/WechatFileSystem.cs new file mode 100644 index 0000000..2061323 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/WechatFileSystem.cs @@ -0,0 +1,188 @@ +#if UNITY_WECHAT_GAME +using System.Collections.Generic; +using UnityEngine; +using YooAsset; +using WeChatWASM; + +public static class WechatFileSystemCreater +{ + public static FileSystemParameters CreateWechatFileSystemParameters(IRemoteServices remoteServices) + { + string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension"; + var fileSystemParams = new FileSystemParameters(fileSystemClass, null); + fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); + return fileSystemParams; + } +} + +/// +/// 微信小游戏文件系统 +/// 参考:https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/Design/UsingAssetBundle.html +/// +internal class WechatFileSystem : IFileSystem +{ + private readonly Dictionary _wxFilePaths = new Dictionary(10000); + private WXFileSystemManager _wxFileSystemMgr; + private string _wxFileCacheRoot = string.Empty; + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件访问权限 + /// + public EFileAccess FileSystemAccess + { + get + { + return EFileAccess.ReadWrite; + } + } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _wxFileCacheRoot; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + #region 自定义参数 + /// + /// 自定义参数:远程服务接口 + /// + public IRemoteServices RemoteServices { private set; get; } = null; + #endregion + + + public WechatFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new WXFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + { + var operation = new WXFSLoadPackageManifestOperation(this, packageVersion, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new WXFSRequestPackageVersionOperation(this, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() + { + var operation = new FSClearAllBundleFilesCompleteOperation(); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest) + { + var operation = new FSClearUnusedBundleFilesCompleteOperation(); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) + { + param.MainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); + param.FallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); + var operation = new WXFSDownloadFileOperation(this, bundle, param); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + var operation = new WXFSLoadBundleOperation(this, bundle); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual void UnloadBundleFile(PackageBundle bundle, object result) + { + AssetBundle assetBundle = result as AssetBundle; + if (assetBundle != null) + assetBundle.WXUnload(true); + } + + public virtual void SetParameter(string name, object value) + { + if (name == "REMOTE_SERVICES") + { + RemoteServices = (IRemoteServices)value; + } + else + { + YooLogger.Warning($"Invalid parameter : {name}"); + } + } + public virtual void OnCreate(string packageName, string rootDirectory) + { + PackageName = packageName; + + _wxFileSystemMgr = WX.GetFileSystemManager(); + _wxFileCacheRoot = WX.env.USER_DATA_PATH; //注意:如果有子目录,请修改此处! + } + public virtual void OnUpdate() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + string filePath = GetWXFileLoadPath(bundle); + string result = _wxFileSystemMgr.AccessSync(filePath); + return result.Equals("access:ok"); + } + 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; + } + + #region 内部方法 + private string GetWXFileLoadPath(PackageBundle bundle) + { + if (_wxFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_wxFileCacheRoot, bundle.FileName); + _wxFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + #endregion +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/WechatFileSystem.cs.meta similarity index 100% rename from Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem.cs.meta rename to Assets/YooAsset/Samples~/Extension Sample/Runtime/WechatFileSystem/WechatFileSystem.cs.meta