From 4c78ed674c418cd3e50dcdfff4012a9ab2d71816 Mon Sep 17 00:00:00 2001 From: stary <834207172@qq.COM> Date: Sat, 18 Apr 2026 23:35:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChangePlayerMode/ChangePlayerMode.cs | 17 +- .../HybridLoad/Fsm/HotFixStartState.cs | 2 +- .../Runtime/Tools/YooAssetFileSystem.cs | 10 +- .../Runtime/com.staryevo.tools.runtime.asmdef | 21 +- Assets/00.StaryEvoTools/WechatFileSystem.meta | 8 + .../WechatFileSystem/BundleResult.meta | 8 + .../BundleResult/WXAssetBundleResult.cs | 67 ++++ .../BundleResult/WXAssetBundleResult.cs.meta | 11 + .../WechatFileSystem/Operation.meta | 8 + .../WXFSClearAllBundleFilesOperation.cs | 57 ++++ .../WXFSClearAllBundleFilesOperation.cs.meta | 11 + .../WXFSClearUnusedBundleFilesAsync.cs | 111 +++++++ .../WXFSClearUnusedBundleFilesAsync.cs.meta | 11 + .../Operation/WXFSDownloadFileOperation.cs | 115 +++++++ .../WXFSDownloadFileOperation.cs.meta | 11 + .../Operation/WXFSInitializeOperation.cs | 20 ++ .../Operation/WXFSInitializeOperation.cs.meta | 11 + .../Operation/WXFSLoadBundleOperation.cs | 88 ++++++ .../Operation/WXFSLoadBundleOperation.cs.meta | 11 + .../WXFSLoadPackageManifestOperation.cs | 95 ++++++ .../WXFSLoadPackageManifestOperation.cs.meta | 11 + .../WXFSRequestPackageVersionOperation.cs | 64 ++++ ...WXFSRequestPackageVersionOperation.cs.meta | 11 + .../WechatFileSystem/Operation/internal.meta | 8 + .../LoadWechatAssetBundleOperation.cs | 115 +++++++ .../LoadWechatAssetBundleOperation.cs.meta | 11 + .../UnityWechatAssetBundleRequestOperation.cs | 96 ++++++ ...yWechatAssetBundleRequestOperation.cs.meta | 11 + .../WechatFileSystem/WechatFileSystem.cs | 294 ++++++++++++++++++ .../WechatFileSystem/WechatFileSystem.cs.meta | 11 + .../WechatFileSystem/YooAsset.MiniGame.asmdef | 20 ++ .../YooAsset.MiniGame.asmdef.meta | 7 + Assets/00.StaryEvoTools/package.json | 2 +- 33 files changed, 1335 insertions(+), 19 deletions(-) create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/BundleResult.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs.meta create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef create mode 100644 Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef.meta diff --git a/Assets/00.StaryEvoTools/Editor/BuildAsset/ChangePlayerMode/ChangePlayerMode.cs b/Assets/00.StaryEvoTools/Editor/BuildAsset/ChangePlayerMode/ChangePlayerMode.cs index c7ab4f8..70414ae 100644 --- a/Assets/00.StaryEvoTools/Editor/BuildAsset/ChangePlayerMode/ChangePlayerMode.cs +++ b/Assets/00.StaryEvoTools/Editor/BuildAsset/ChangePlayerMode/ChangePlayerMode.cs @@ -15,11 +15,11 @@ namespace Stary.Evo.Editor private static PLayerMode _pLayerMode; - private const string EditorSimulateMode = "Evo/Schema/ChangePlayer/EditorSimulateMode(编辑器调试模式)"; - private const string HostPlayMode = "Evo/Schema/ChangePlayer/HostPlayMode(联机运行模式)"; - private const string LocalPlayMode = "Evo/Schema/ChangePlayer/LocalPlayMode(本地运行模式)"; - private const string WebPlayMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web运行模式)"; - + private const string EditorSimulateMode = "Evo/Schema/ChangePlayer/EditorSimulateMode(调试)"; + private const string HostPlayMode = "Evo/Schema/ChangePlayer/HostPlayMode(联机)"; + private const string LocalPlayMode = "Evo/Schema/ChangePlayer/LocalPlayMode(本地)"; + private const string WebPlayMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web)/WebNormal(正常)"; + private const string WeChatPlayMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web)/WeChatPlayMode(微信)"; [MenuItem(EditorSimulateMode, false,3)] private static void SetEditorMode() => SetPlayerMode(PLayerMode.EDITOR_SIMULATEMODE); [MenuItem(HostPlayMode, false,3)] @@ -28,6 +28,8 @@ namespace Stary.Evo.Editor private static void SetLocalMode() => SetPlayerMode(PLayerMode.LOCAL_PLAYMODE); [MenuItem(WebPlayMode)] private static void SetWebMode() => SetPlayerMode(PLayerMode.WEB_PLAYMODE); + [MenuItem(WeChatPlayMode)] + private static void SetWeChatModeMode() => SetPlayerMode(PLayerMode.WEIXINMINIGAME); [MenuItem(EditorSimulateMode, true,3)] private static bool ValidateModeMenu() @@ -37,6 +39,7 @@ namespace Stary.Evo.Editor Menu.SetChecked(HostPlayMode, platform == PLayerMode.HOST_PLAYMODE.ToString()); Menu.SetChecked(LocalPlayMode, platform == PLayerMode.LOCAL_PLAYMODE.ToString()); Menu.SetChecked(WebPlayMode, platform == PLayerMode.WEB_PLAYMODE.ToString()); + Menu.SetChecked(WeChatPlayMode, platform == PLayerMode.WEIXINMINIGAME.ToString()); Debug.Log($"ChangePlayerSchema:{platform}"); return true; } @@ -79,6 +82,8 @@ namespace Stary.Evo.Editor //本地运行模式 LOCAL_PLAYMODE, // //web运行模式 - WEB_PLAYMODE + WEB_PLAYMODE, + + WEIXINMINIGAME } } \ No newline at end of file diff --git a/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs b/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs index a9c0d82..5732947 100644 --- a/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs +++ b/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs @@ -76,7 +76,7 @@ namespace Stary.Evo if (isInitSuccess) await UpdateLocalPackage(packageRawFile); await LoadHotfixSettings(); -#elif WEB_PLAYMODE +#elif WEB_PLAYMODE || WECHAT_PLAYMODE await WEB_PLAYMODE(package); await UpdateLocalPackage(package); diff --git a/Assets/00.StaryEvoTools/Runtime/Tools/YooAssetFileSystem.cs b/Assets/00.StaryEvoTools/Runtime/Tools/YooAssetFileSystem.cs index c8bb183..86b61a8 100644 --- a/Assets/00.StaryEvoTools/Runtime/Tools/YooAssetFileSystem.cs +++ b/Assets/00.StaryEvoTools/Runtime/Tools/YooAssetFileSystem.cs @@ -30,8 +30,14 @@ namespace Stary.Evo { IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer); //var webServerFileSystemParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); - var webRemoteFileSystemParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载 - + +#if UNITY_WEBGL&&WEB_PLAYMODE + var webRemoteFileSystemParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载 +#elif UNITY_WEBGL && WEIXINMINIGAME + string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE"; + var webRemoteFileSystemParams= WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices); +#endif + var initParameters = new WebPlayModeParameters(); //initParameters.WebServerFileSystemParameters = webRemoteFileSystemParams; initParameters.WebRemoteFileSystemParameters = webRemoteFileSystemParams; diff --git a/Assets/00.StaryEvoTools/Runtime/com.staryevo.tools.runtime.asmdef b/Assets/00.StaryEvoTools/Runtime/com.staryevo.tools.runtime.asmdef index bd6a345..0fcdf05 100644 --- a/Assets/00.StaryEvoTools/Runtime/com.staryevo.tools.runtime.asmdef +++ b/Assets/00.StaryEvoTools/Runtime/com.staryevo.tools.runtime.asmdef @@ -2,18 +2,21 @@ "name": "com.staryevo.tools.runtime", "rootNamespace": "", "references": [ - "UniTask", - "com.audiocore.runtime", - "com.stary.evo.runtime", - "Informationsave.runtime", - "DOTween.Modules", - "com.stary.buildoriginality.runtime", - "YooAsset", - "HybridCLR.Runtime" + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:aa8669166ad4e984bb229dc22e7b1e02", + "GUID:d1a793c2b6959e04ea45b972eaa369c8", + "GUID:ec45849e30ba03e4dab386099d8c697b", + "GUID:fad681b9bfe621d4fa07f4f69c311443", + "GUID:8c6fa7c2cd7bf784e856d9adb3dc2ada", + "GUID:e34a5702dd353724aa315fb8011f08c3", + "GUID:13ba8ce62aa80c74598530029cb2d649", + "GUID:5efd170ecd8084500bed5692932fe14e", + "GUID:5830d4a11fa1e8f46a8e7ea664a8de75", + "GUID:839b8c2cb327b8a43afe86fd33563571" ], "includePlatforms": [], "excludePlatforms": [], - "allowUnsafeCode": true, + "allowUnsafeCode": false, "overrideReferences": false, "precompiledReferences": [], "autoReferenced": true, diff --git a/Assets/00.StaryEvoTools/WechatFileSystem.meta b/Assets/00.StaryEvoTools/WechatFileSystem.meta new file mode 100644 index 0000000..c4ccea8 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f56961600a362a847b0a6ef1c21e8579 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult.meta b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult.meta new file mode 100644 index 0000000..19f80d0 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2273a844c27632c4c8c1de56b4cfd8d1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs new file mode 100644 index 0000000..80510bd --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs @@ -0,0 +1,67 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using System.IO; +using UnityEngine; +using UnityEngine.SceneManagement; +using WeChatWASM; + +namespace YooAsset +{ + internal class WXAssetBundleResult : BundleResult + { + private readonly IFileSystem _fileSystem; + private readonly PackageBundle _packageBundle; + private readonly AssetBundle _assetBundle; + + public WXAssetBundleResult(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.WXUnload(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/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs.meta new file mode 100644 index 0000000..ec3e68d --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/BundleResult/WXAssetBundleResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 901960117d0627544af4959316d467b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation.meta new file mode 100644 index 0000000..f4e4b86 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f3e1fc2487de40346b26fb3af71c0f88 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs new file mode 100644 index 0000000..893fdf7 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs @@ -0,0 +1,57 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using YooAsset; +using WeChatWASM; + +internal class WXFSClearAllBundleFilesOperation : FSClearCacheFilesOperation +{ + private enum ESteps + { + None, + ClearAllCacheFiles, + WaitResult, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + internal WXFSClearAllBundleFilesOperation(WechatFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + internal override void InternalStart() + { + _steps = ESteps.ClearAllCacheFiles; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.ClearAllCacheFiles) + { + _steps = ESteps.WaitResult; + + WX.CleanAllFileCache((bool isOk) => + { + if (isOk) + { + YooLogger.Log("微信缓存清理成功!"); + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + YooLogger.Log("微信缓存清理失败!"); + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "微信缓存清理失败!"; + } + }); + } + } +} +#endif diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs.meta new file mode 100644 index 0000000..d0ea596 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearAllBundleFilesOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eef9c14836ca93346ba50fd29cbf9fcc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs new file mode 100644 index 0000000..c54e1d4 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs @@ -0,0 +1,111 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using System.Collections.Generic; +using System.IO; +using System.Linq; +using YooAsset; +using WeChatWASM; + +internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation +{ + private enum ESteps + { + None, + GetUnusedCacheFiles, + WaitingSearch, + ClearUnusedCacheFiles, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly PackageManifest _manifest; + private List _unusedCacheFiles = new List(1000); + private int _unusedFileTotalCount = 0; + private ESteps _steps = ESteps.None; + + internal WXFSClearUnusedBundleFilesAsync(WechatFileSystem fileSystem, PackageManifest manifest) + { + _fileSystem = fileSystem; + _manifest = manifest; + } + internal override void InternalStart() + { + _steps = ESteps.GetUnusedCacheFiles; + } + internal override void InternalUpdate() + { + if (_steps == ESteps.None || _steps == ESteps.Done) + return; + + if (_steps == ESteps.GetUnusedCacheFiles) + { + _steps = ESteps.WaitingSearch; + + // 说明:__GAME_FILE_CACHE/yoo/ 目录下包含所有的资源文件和清单文件 + var fileSystemMgr = _fileSystem.GetFileSystemMgr(); + var statOption = new WXStatOption(); + statOption.path = _fileSystem.FileRoot; + statOption.recursive = true; + statOption.success = (WXStatResponse response) => + { + foreach (var fileStat in response.stats) + { + // 如果是目录文件 + string fileExtension = Path.GetExtension(fileStat.path); + if (string.IsNullOrEmpty(fileExtension)) + continue; + + // 如果是资源清单 + //TODO 默认的清单文件格式 + if (fileExtension == ".bytes" || fileExtension == ".hash") + continue; + + // 注意:适配不同的文件命名方式! + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileStat.path); + string bundleGUID = fileNameWithoutExtension.Split('_').Last(); + if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false) + { + string filePath = _fileSystem.FileRoot + fileStat.path; + if (_unusedCacheFiles.Contains(filePath) == false) + _unusedCacheFiles.Add(filePath); + } + } + + _steps = ESteps.ClearUnusedCacheFiles; + _unusedFileTotalCount = _unusedCacheFiles.Count; + YooLogger.Log($"Found unused cache files count : {_unusedFileTotalCount}"); + }; + statOption.fail = (WXStatResponse response) => + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = response.errMsg; + }; + fileSystemMgr.Stat(statOption); + } + + if (_steps == ESteps.ClearUnusedCacheFiles) + { + for (int i = _unusedCacheFiles.Count - 1; i >= 0; i--) + { + string filePath = _unusedCacheFiles[i]; + _unusedCacheFiles.RemoveAt(i); + WX.RemoveFile(filePath, null); + + if (OperationSystem.IsBusy) + break; + } + + if (_unusedFileTotalCount == 0) + Progress = 1.0f; + else + Progress = 1.0f - (_unusedCacheFiles.Count / _unusedFileTotalCount); + + if (_unusedCacheFiles.Count == 0) + { + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs.meta new file mode 100644 index 0000000..afb8199 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSClearUnusedBundleFilesAsync.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c0927ce5425fe443a7c88f4fc46a7c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs new file mode 100644 index 0000000..88ed1d7 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs @@ -0,0 +1,115 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using UnityEngine; +using YooAsset; + +internal class WXFSDownloadFileOperation : FSDownloadFileOperation +{ + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly DownloadFileOptions _options; + private UnityWebCacheRequestOperation _webCacheRequestOp; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + private ESteps _steps = ESteps.None; + + internal WXFSDownloadFileOperation(WechatFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle) + { + _fileSystem = fileSystem; + _options = options; + _failedTryAgain = options.FailedTryAgain; + } + internal override void InternalStart() + { + _steps = ESteps.CreateRequest; + } + internal override void InternalUpdate() + { + // 创建下载器 + if (_steps == ESteps.CreateRequest) + { + string url = GetRequestURL(); + _webCacheRequestOp = new UnityWebCacheRequestOperation(url); + _webCacheRequestOp.SetRequestHeader("wechatminigame-preload", "1"); + _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 解决微信小游戏插件问题 + // Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108# + 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/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta new file mode 100644 index 0000000..7bdc67d --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b68ed83f5520b04d82c82da8f8f13a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs new file mode 100644 index 0000000..2468902 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs @@ -0,0 +1,20 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using YooAsset; + +internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation +{ + private readonly WechatFileSystem _fileSystem; + + public WXFSInitializeOperation(WechatFileSystem 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/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta new file mode 100644 index 0000000..09c87fe --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfbe92cc9e2c1664980c6663aac606a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs new file mode 100644 index 0000000..ccdb141 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using YooAsset; + +internal class WXFSLoadBundleOperation : FSLoadBundleOperation +{ + private enum ESteps + { + None, + LoadAssetBundle, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private LoadWebAssetBundleOperation _loadWebAssetBundleOp; + private ESteps _steps = ESteps.None; + + internal WXFSLoadBundleOperation(WechatFileSystem 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 LoadWechatAssetBundleOperation(_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 WXAssetBundleResult(_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/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta new file mode 100644 index 0000000..4069120 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0591f444ec236f499e608d1efc09b4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs new file mode 100644 index 0000000..4759c72 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs @@ -0,0 +1,95 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using YooAsset; + +internal class WXFSLoadPackageManifestOperation : FSLoadPackageManifestOperation +{ + private enum ESteps + { + None, + RequestPackageHash, + LoadPackageManifest, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private RequestWebPackageHashOperation _requestPackageHashOp; + private LoadWebPackageManifestOperation _loadPackageManifestOp; + private ESteps _steps = ESteps.None; + + + public WXFSLoadPackageManifestOperation(WechatFileSystem 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 RequestWebPackageHashOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _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; + string packageName = _fileSystem.PackageName; + var manifestServices = _fileSystem.ManifestServices; + var remoteServices = _fileSystem.RemoteServices; + _loadPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, packageName, _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/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 0000000..329612e --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7ba664d33c1ec54d99e426c360b4e2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs new file mode 100644 index 0000000..66a82a6 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs @@ -0,0 +1,64 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using YooAsset; + +internal class WXFSRequestPackageVersionOperation : FSRequestPackageVersionOperation +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly WechatFileSystem _fileSystem; + private readonly bool _appendTimeTicks; + private readonly int _timeout; + private RequestWebPackageVersionOperation _requestWebPackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal WXFSRequestPackageVersionOperation(WechatFileSystem 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 RequestWebPackageVersionOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _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/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 0000000..256e886 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/WXFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5180674a9ce18da4b90dba6b36c1efe4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal.meta new file mode 100644 index 0000000..17c9709 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5744a1caf86e5e444945d8f83bfe65d0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs new file mode 100644 index 0000000..5217a00 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs @@ -0,0 +1,115 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using UnityEngine; + +namespace YooAsset +{ + internal class LoadWechatAssetBundleOperation : LoadWebAssetBundleOperation + { + protected enum ESteps + { + None, + CreateRequest, + CheckRequest, + TryAgain, + Done, + } + + private readonly PackageBundle _bundle; + private readonly DownloadFileOptions _options; + private UnityWechatAssetBundleRequestOperation _unityAssetBundleRequestOp; + + private int _requestCount = 0; + private float _tryAgainTimer = 0; + private int _failedTryAgain; + private ESteps _steps = ESteps.None; + + + internal LoadWechatAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) + { + _bundle = bundle; + _options = options; + _failedTryAgain = options.FailedTryAgain; + } + 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 UnityWechatAssetBundleRequestOperation(_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; + } + } + } + + /// + /// 获取网络请求地址 + /// + protected 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/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs.meta new file mode 100644 index 0000000..149ad46 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/LoadWechatAssetBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ccd1061504155f44847e21683b57ec7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs new file mode 100644 index 0000000..741970b --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs @@ -0,0 +1,96 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using UnityEngine.Networking; +using UnityEngine; +using WeChatWASM; + +namespace YooAsset +{ + internal class UnityWechatAssetBundleRequestOperation : 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 UnityWechatAssetBundleRequestOperation(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 = (DownloadHandlerWXAssetBundle)_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 解决微信小游戏插件问题 + // Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108# + DownloadProgress = 1f; + DownloadedBytes = _packageBundle.FileSize; + Progress = 1f; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + + // 注意:最终释放请求器 + DisposeRequest(); + } + } + + private void CreateWebRequest() + { + _webRequest = WXAssetBundle.GetAssetBundle(_requestURL); + _webRequest.disposeDownloadHandlerOnDispose = true; + _requestOperation = _webRequest.SendWebRequest(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs.meta new file mode 100644 index 0000000..74f8bb0 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/Operation/internal/UnityWechatAssetBundleRequestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c66c1c3728b99b74fbfe1363e3e76704 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs b/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs new file mode 100644 index 0000000..a02a4e9 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs @@ -0,0 +1,294 @@ +#if UNITY_WEBGL && WEIXINMINIGAME +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using YooAsset; +using WeChatWASM; + +public static class WechatFileSystemCreater +{ + public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices) + { + string fileSystemClass = $"{nameof(WechatFileSystem)},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(WechatFileSystem)},YooAsset.MiniGame"; + var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot); + fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); + fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices); + return fileSystemParams; + } +} + +/// +/// 微信小游戏文件系统 +/// 参考:https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/Design/UsingAssetBundle.html +/// +internal class WechatFileSystem : 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 WXFileSystemManager _fileSystemMgr; + private string _wxCacheRoot = string.Empty; + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return _wxCacheRoot; + } + } + + /// + /// 文件数量 + /// + 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 WechatFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new WXFSInitializeOperation(this); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + { + var operation = new WXFSLoadPackageManifestOperation(this, packageVersion, timeout); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new WXFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); + return operation; + } + public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options) + { + if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString()) + { + var operation = new WXFSClearAllBundleFilesOperation(this); + return operation; + } + else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) + { + var operation = new WXFSClearUnusedBundleFilesAsync(this, manifest); + return operation; + } + else + { + string error = $"Invalid clear mode : {options.ClearMode}"; + var operation = new FSClearCacheFilesCompleteOperation(error); + 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 WXFSDownloadFileOperation(this, bundle, options); + return operation; + } + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + if (bundle.BundleType == (int)EBuildBundleType.AssetBundle) + { + var operation = new WXFSLoadBundleOperation(this, bundle); + return operation; + } + else + { + string error = $"{nameof(WechatFileSystem)} 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 packageRoot) + { + PackageName = packageName; + _wxCacheRoot = packageRoot; + + if (string.IsNullOrEmpty(_wxCacheRoot)) + { + throw new System.Exception("请配置小游戏缓存根目录!"); + } + + // 注意:CDN服务未启用的情况下,使用WEB服务器 + if (RemoteServices == null) + { + string webRoot = PathUtility.Combine(Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName, packageName); + RemoteServices = new WebRemoteServices(webRoot); + } + + // 检查URL双斜杠 + // 注意:双斜杠会导致微信插件加载文件失败,但网络请求又不返回失败! + { + var mainURL = RemoteServices.GetRemoteMainURL("test.bundle"); + var fallbackURL = RemoteServices.GetRemoteFallbackURL("test.bundle"); + if (PathUtility.HasDoubleSlashes(mainURL) || PathUtility.HasDoubleSlashes(fallbackURL)) + throw new Exception($"{nameof(RemoteServices)} returned URL contains double slashes. !"); + } + + _fileSystemMgr = WX.GetFileSystemManager(); + } + public virtual void OnDestroy() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + string filePath = GetCacheFileLoadPath(bundle); + return CheckCacheFileExist(filePath); + } + 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) + { + string filePath = GetCacheFileLoadPath(bundle); + if (CheckCacheFileExist(filePath)) + return _fileSystemMgr.ReadFileSync(filePath); + else + return Array.Empty(); + } + public virtual string ReadBundleFileText(PackageBundle bundle) + { + string filePath = GetCacheFileLoadPath(bundle); + if (CheckCacheFileExist(filePath)) + return _fileSystemMgr.ReadFileSync(filePath, "utf8"); + else + return string.Empty; + } + + #region 内部方法 + public WXFileSystemManager GetFileSystemMgr() + { + return _fileSystemMgr; + } + public bool CheckCacheFileExist(string filePath) + { + string result = WX.GetCachePath(filePath); + if (string.IsNullOrEmpty(result)) + return false; + else + return true; + } + public string GetCacheFileLoadPath(PackageBundle bundle) + { + if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = PathUtility.Combine(_wxCacheRoot, bundle.FileName); + _cacheFilePathMapping.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + #endregion +} +#endif \ No newline at end of file diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs.meta b/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs.meta new file mode 100644 index 0000000..8f84385 --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/WechatFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 455d22ddaed45254380567dce5125d67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef b/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef new file mode 100644 index 0000000..16ec23a --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef @@ -0,0 +1,20 @@ +{ + "name": "YooAsset.MiniGame", + "rootNamespace": "", + "references": [ + "GUID:e34a5702dd353724aa315fb8011f08c3", + "GUID:5efd170ecd8084500bed5692932fe14e", + "GUID:bb21d6197862c4c3e863390dec9859a7", + "GUID:870f26a2ffa82429195df0861505c5d5", + "GUID:6921e41464907054da1a045ea64ca16f" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef.meta b/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef.meta new file mode 100644 index 0000000..e68275e --- /dev/null +++ b/Assets/00.StaryEvoTools/WechatFileSystem/YooAsset.MiniGame.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5830d4a11fa1e8f46a8e7ea664a8de75 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/00.StaryEvoTools/package.json b/Assets/00.StaryEvoTools/package.json index 9a3382d..82cc4ad 100644 --- a/Assets/00.StaryEvoTools/package.json +++ b/Assets/00.StaryEvoTools/package.json @@ -1,6 +1,6 @@ { "name": "com.staryevo.tools", - "version": "1.4.22", + "version": "1.4.23", "displayName": "00.StaryEvo.Tools", "description": "This is an Framework package(后台服务器版本,端口9527)", "unity": "2021.3",