diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem.meta new file mode 100644 index 0000000..cff102c --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ccb22c5c90bfe2f43a0f83f873dd6646 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs new file mode 100644 index 0000000..db00534 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs @@ -0,0 +1,219 @@ +#if UNITY_WEBGL +using System.Collections.Generic; +using UnityEngine; +using YooAsset; +using StarkSDKSpace; + +public static class ByteGameFileSystemCreater +{ + public static FileSystemParameters CreateWechatFileSystemParameters(IRemoteServices remoteServices) + { + string fileSystemClass = $"{nameof(ByteGameFileSystem)},YooAsset.RuntimeExtension"; + var fileSystemParams = new FileSystemParameters(fileSystemClass, null); + fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices); + return fileSystemParams; + } +} + +/// +/// 抖音小游戏文件系统 +/// 参考:https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/guide/know +/// +internal class ByteGameFileSystem : 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 _cacheFilePaths = new Dictionary(10000); + private StarkFileSystemManager _fileSystemManager; + + /// + /// 包裹名称 + /// + public string PackageName { private set; get; } + + /// + /// 文件根目录 + /// + public string FileRoot + { + get + { + return string.Empty; + } + } + + /// + /// 文件数量 + /// + public int FileCount + { + get + { + return 0; + } + } + + #region 自定义参数 + /// + /// 自定义参数:远程服务接口 + /// + public IRemoteServices RemoteServices { private set; get; } = null; + #endregion + + + public ByteGameFileSystem() + { + } + public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync() + { + var operation = new BGFSInitializeOperation(this); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout) + { + var operation = new BGFSLoadPackageManifestOperation(this, packageVersion, timeout); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout) + { + var operation = new BGFSRequestPackageVersionOperation(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 BGFSDownloadFileOperation(this, bundle, param); + OperationSystem.StartOperation(PackageName, operation); + return operation; + } + public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) + { + var operation = new BGFSLoadBundleOperation(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.Unload(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; + + // 注意:CDN服务未启用的情况下,使用抖音WEB服务器 + if (RemoteServices == null) + { + string webRoot = PathUtility.Combine(Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName, packageName); + RemoteServices = new WebRemoteServices(webRoot); + } + + _fileSystemManager = StarkSDK.API.GetStarkFileSystemManager(); + } + public virtual void OnUpdate() + { + } + + public virtual bool Belong(PackageBundle bundle) + { + return true; + } + public virtual bool Exists(PackageBundle bundle) + { + return _fileSystemManager.AccessSync(bundle.FileName); + } + 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 byte[] ReadFileData(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + public virtual string ReadFileText(PackageBundle bundle) + { + throw new System.NotImplementedException(); + } + + #region 内部方法 + private string GetFileLoadPath(PackageBundle bundle) + { + if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false) + { + filePath = _fileSystemManager.GetLocalCachedPathForUrl(bundle.FileName); + _cacheFilePaths.Add(bundle.BundleGUID, filePath); + } + return filePath; + } + #endregion +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs.meta new file mode 100644 index 0000000..ac1a607 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/ByteGameFileSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6b4324eddc60f045aa271bc5bb50cc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation.meta new file mode 100644 index 0000000..7e4113c --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8cba5e0b26df8ee40a93d697f889e33d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs new file mode 100644 index 0000000..611d685 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs @@ -0,0 +1,101 @@ +#if UNITY_WEBGL +using UnityEngine; +using UnityEngine.Networking; +using YooAsset; + +internal class BGFSDownloadFileOperation : DefaultDownloadFileOperation +{ + private ByteGameFileSystem _fileSystem; + private ESteps _steps = ESteps.None; + + internal BGFSDownloadFileOperation(ByteGameFileSystem 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() + { + //TODO : 抖音小游戏没有找到预下载方法 + _webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_requestURL); + _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/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs.meta new file mode 100644 index 0000000..b3abf50 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSDownloadFileOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0bdf53359f9e17b41b08982a2be2098c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs new file mode 100644 index 0000000..8beec7f --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs @@ -0,0 +1,20 @@ +#if UNITY_WEBGL +using YooAsset; + +internal partial class BGFSInitializeOperation : FSInitializeFileSystemOperation +{ + private readonly ByteGameFileSystem _fileSystem; + + public BGFSInitializeOperation(ByteGameFileSystem 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/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs.meta new file mode 100644 index 0000000..e6e0ca6 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSInitializeOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 614227bf558da7149a7eb6de7dfa1a21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs new file mode 100644 index 0000000..790f677 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs @@ -0,0 +1,102 @@ +#if UNITY_WEBGL +using UnityEditor.PackageManager.Requests; +using UnityEngine; +using UnityEngine.Networking; +using YooAsset; + +internal class BGFSLoadBundleOperation : FSLoadBundleOperation +{ + private enum ESteps + { + None, + LoadBundleFile, + Done, + } + + private readonly ByteGameFileSystem _fileSystem; + private readonly PackageBundle _bundle; + private UnityWebRequest _webRequest; + private ESteps _steps = ESteps.None; + + internal BGFSLoadBundleOperation(ByteGameFileSystem 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 = UnityWebRequestAssetBundle.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 DownloadHandlerAssetBundle).assetBundle; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + } + } + } + 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); + } + } + 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/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs.meta new file mode 100644 index 0000000..2b1312a --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadBundleOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19997de7b89b54445961e8b973f43ab3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs new file mode 100644 index 0000000..7a0d0b1 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WEBGL +using YooAsset; + +internal class BGFSLoadPackageManifestOperation : FSLoadPackageManifestOperation +{ + private enum ESteps + { + None, + RequestRemotePackageHash, + LoadRemotePackageManifest, + Done, + } + + private readonly ByteGameFileSystem _fileSystem; + private readonly string _packageVersion; + private readonly int _timeout; + private RequestByteGamePackageHashOperation _requestRemotePackageHashOp; + private LoadByteGamePackageManifestOperation _loadRemotePackageManifestOp; + private ESteps _steps = ESteps.None; + + + public BGFSLoadPackageManifestOperation(ByteGameFileSystem 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 RequestByteGamePackageHashOperation(_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 LoadByteGamePackageManifestOperation(_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/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs.meta new file mode 100644 index 0000000..7b4505f --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSLoadPackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2850c0b0e742f824f9d1f12b7d68b806 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs new file mode 100644 index 0000000..0b2a91f --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs @@ -0,0 +1,60 @@ +#if UNITY_WEBGL +using YooAsset; + +internal class BGFSRequestPackageVersionOperation : FSRequestPackageVersionOperation +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly ByteGameFileSystem _fileSystem; + private readonly int _timeout; + private RequestByteGamePackageVersionOperation _requestWebPackageVersionOp; + private ESteps _steps = ESteps.None; + + + internal BGFSRequestPackageVersionOperation(ByteGameFileSystem 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 RequestByteGamePackageVersionOperation(_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/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs.meta new file mode 100644 index 0000000..80e9802 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/BGFSRequestPackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8210185faba92a3479bf6713abab1f19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal.meta new file mode 100644 index 0000000..6df9ad2 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 101c97835f86e9147993961f514caf2c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs new file mode 100644 index 0000000..395a5e3 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs @@ -0,0 +1,125 @@ +#if UNITY_WEBGL +using YooAsset; + +internal class LoadByteGamePackageManifestOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestFileData, + VerifyFileData, + LoadManifest, + Done, + } + + private readonly ByteGameFileSystem _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 LoadByteGamePackageManifestOperation(ByteGameFileSystem 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(LoadByteGamePackageManifestOperation)); + _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(LoadByteGamePackageManifestOperation)); + } + } + + 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/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs.meta new file mode 100644 index 0000000..6bb1e19 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/LoadByteGamePackageManifestOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b648d648fa0c4e44d811b42b80891543 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs new file mode 100644 index 0000000..7cfb018 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs @@ -0,0 +1,90 @@ +#if UNITY_WEBGL +using YooAsset; + +internal class RequestByteGamePackageHashOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageHash, + Done, + } + + private readonly ByteGameFileSystem _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 RequestByteGamePackageHashOperation(ByteGameFileSystem fileSystem, string packageVersion, int timeout) + { + _fileSystem = fileSystem; + _packageVersion = packageVersion; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestByteGamePackageHashOperation)); + _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(RequestByteGamePackageHashOperation)); + } + } + } + + 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/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs.meta new file mode 100644 index 0000000..7a99745 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageHashOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51a0e40e248b49a4783b3dca33a23cf1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs new file mode 100644 index 0000000..963deaf --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs @@ -0,0 +1,88 @@ +#if UNITY_WEBGL +using YooAsset; + +internal class RequestByteGamePackageVersionOperation : AsyncOperationBase +{ + private enum ESteps + { + None, + RequestPackageVersion, + Done, + } + + private readonly ByteGameFileSystem _fileSystem; + private readonly int _timeout; + private UnityWebTextRequestOperation _webTextRequestOp; + private int _requestCount = 0; + private ESteps _steps = ESteps.None; + + /// + /// 包裹版本 + /// + public string PackageVersion { private set; get; } + + + public RequestByteGamePackageVersionOperation(ByteGameFileSystem fileSystem, int timeout) + { + _fileSystem = fileSystem; + _timeout = timeout; + } + internal override void InternalOnStart() + { + _requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestByteGamePackageVersionOperation)); + _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(RequestByteGamePackageVersionOperation)); + } + } + } + + 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/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs.meta new file mode 100644 index 0000000..be04d19 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/ByteGameFileSystem/Operation/internal/RequestByteGamePackageVersionOperation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a04c463fb00f60f499541fbb98e4fdc4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/YooAsset.RuntimeExtension.asmdef b/Assets/YooAsset/Samples~/Extension Sample/Runtime/YooAsset.RuntimeExtension.asmdef index 1440681..3095837 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/YooAsset.RuntimeExtension.asmdef +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/YooAsset.RuntimeExtension.asmdef @@ -3,7 +3,8 @@ "rootNamespace": "", "references": [ "GUID:e34a5702dd353724aa315fb8011f08c3", - "GUID:5efd170ecd8084500bed5692932fe14e" + "GUID:5efd170ecd8084500bed5692932fe14e", + "GUID:0f8df04a5a494444eb8fa0504f6fb965" ], "includePlatforms": [], "excludePlatforms": [],