From 47f5790507133f992f6f277a7c0a80695c915555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E5=86=A0=E5=B3=B0?= Date: Thu, 27 Feb 2025 10:31:05 +0800 Subject: [PATCH] update resource package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CreateBundleDownloader下载器增加参数:recursiveDownload --- .../ResourcePackage/Interface/IPlayMode.cs | 2 +- .../Operation/PreDownloadContentOperation.cs | 24 ++++++------- .../ResourcePackage/PackageManifest.cs | 22 ++++++++---- .../PlayMode/EditorSimulateModeImpl.cs | 4 +-- .../PlayMode/HostPlayModeImpl.cs | 4 +-- .../PlayMode/OfflinePlayModeImpl.cs | 4 +-- .../PlayMode/PlayModeHelper.cs | 24 +++++++++++-- .../PlayMode/WebPlayModeImpl.cs | 4 +-- .../ResourcePackage/ResourcePackage.cs | 36 ++++++++++++++----- 9 files changed, 85 insertions(+), 39 deletions(-) diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs index 5535ee7a..d4b45496 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Interface/IPlayMode.cs @@ -36,7 +36,7 @@ namespace YooAsset // 下载相关 ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout); - ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout); + ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout); // 解压相关 ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout); diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs index 3e498bd7..e7825220 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/PreDownloadContentOperation.cs @@ -43,7 +43,7 @@ namespace YooAsset /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public abstract ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60); + public abstract ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60); /// /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 @@ -52,7 +52,7 @@ namespace YooAsset /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public abstract ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60); + public abstract ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60); } internal class EditorSimulateModePreDownloadContentOperation : PreDownloadContentOperation @@ -83,11 +83,11 @@ namespace YooAsset { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } @@ -120,11 +120,11 @@ namespace YooAsset { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } @@ -256,7 +256,7 @@ namespace YooAsset var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { @@ -268,11 +268,11 @@ namespace YooAsset var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null); assetInfos.Add(assetInfo); - List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), _impl.BuildinFileSystem, _impl.CacheFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), recursiveDownload, _impl.BuildinFileSystem, _impl.CacheFileSystem); var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { if (Status != EOperationStatus.Succeed) { @@ -287,7 +287,7 @@ namespace YooAsset assetInfos.Add(assetInfo); } - List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), _impl.BuildinFileSystem, _impl.CacheFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(_manifest, assetInfos.ToArray(), recursiveDownload, _impl.BuildinFileSystem, _impl.CacheFileSystem); var operation = new ResourceDownloaderOperation(_impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } @@ -320,11 +320,11 @@ namespace YooAsset { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } - public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout); } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs index 955eb8cf..fbc1e0d5 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageManifest.cs @@ -188,13 +188,7 @@ namespace YooAsset { if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset)) { - List result = new List(packageAsset.DependBundleIDs.Length); - foreach (var dependID in packageAsset.DependBundleIDs) - { - var dependBundle = GetMainPackageBundle(dependID); - result.Add(dependBundle); - } - return result.ToArray(); + return GetAllDependencies(packageAsset); } else { @@ -202,6 +196,20 @@ namespace YooAsset } } + /// + /// 获取资源依赖列表 + /// + public PackageBundle[] GetAllDependencies(PackageAsset packageAsset) + { + List result = new List(packageAsset.DependBundleIDs.Length); + foreach (var dependID in packageAsset.DependBundleIDs) + { + var dependBundle = GetMainPackageBundle(dependID); + result.Add(dependBundle); + } + return result.ToArray(); + } + /// /// 尝试获取包裹的资源 /// diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs index 24e263a7..3a70c0cf 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/EditorSimulateModeImpl.cs @@ -71,9 +71,9 @@ namespace YooAsset var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, EditorFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload, EditorFileSystem); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs index 566c17a0..c8ae44e8 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/HostPlayModeImpl.cs @@ -74,9 +74,9 @@ namespace YooAsset var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, BuildinFileSystem, CacheFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload, BuildinFileSystem, CacheFileSystem); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs index 305dd929..75316285 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/OfflinePlayModeImpl.cs @@ -71,9 +71,9 @@ namespace YooAsset var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, BuildinFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload, BuildinFileSystem); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs index e1691257..43878f8d 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/PlayModeHelper.cs @@ -84,7 +84,7 @@ namespace YooAsset } return result; } - public static List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) + public static List GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload, IFileSystem fileSystemA = null, IFileSystem fileSystemB = null, IFileSystem fileSystemC = null) { // 获取资源对象的资源包和所有依赖资源包 List checkList = new List(); @@ -102,12 +102,30 @@ namespace YooAsset checkList.Add(mainBundle); // 注意:如果清单里未找到资源包会抛出异常! - PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); - foreach (var dependBundle in dependBundles) + PackageBundle[] mainDependBundles = manifest.GetAllDependencies(assetInfo.AssetPath); + foreach (var dependBundle in mainDependBundles) { if (checkList.Contains(dependBundle) == false) checkList.Add(dependBundle); } + + // 下载主资源包内所有资源对象依赖的资源包 + if (recursiveDownload) + { + foreach (var otherMainAsset in mainBundle.IncludeMainAssets) + { + var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID); + if (checkList.Contains(otherMainBundle) == false) + checkList.Add(otherMainBundle); + + PackageBundle[] otherDependBundles = manifest.GetAllDependencies(otherMainAsset); + foreach (var dependBundle in otherDependBundles) + { + if (checkList.Contains(dependBundle) == false) + checkList.Add(dependBundle); + } + } + } } List result = new List(1000); diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs index 626c6849..957e7db8 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PlayMode/WebPlayModeImpl.cs @@ -93,9 +93,9 @@ namespace YooAsset var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } - ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout) + ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout) { - List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, WebServerFileSystem, WebRemoteFileSystem); + List downloadList = PlayModeHelper.GetDownloadListByPaths(ActiveManifest, assetInfos, recursiveDownload, WebServerFileSystem, WebRemoteFileSystem); var operation = new ResourceDownloaderOperation(PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 0271de5f..93007c40 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -984,25 +984,31 @@ namespace YooAsset /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 /// /// 资源的定位地址 + /// 下载资源对象所属资源包内所有资源对象依赖的资源包 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); var assetInfo = ConvertLocationToAssetInfo(location, null); AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain, timeout); + } + public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + return CreateBundleDownloader(location, false, downloadingMaxNumber, failedTryAgain, timeout); } /// /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 /// /// 资源的定位地址列表 + /// 下载资源对象所属资源包内所有资源对象依赖的资源包 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); List assetInfos = new List(locations.Length); @@ -1011,34 +1017,48 @@ namespace YooAsset var assetInfo = ConvertLocationToAssetInfo(location, null); assetInfos.Add(assetInfo); } - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos.ToArray(), downloadingMaxNumber, failedTryAgain, timeout); + return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos.ToArray(), recursiveDownload, downloadingMaxNumber, failedTryAgain, timeout); + } + public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + return CreateBundleDownloader(locations, false, downloadingMaxNumber, failedTryAgain, timeout); } /// /// 创建资源下载器,用于下载指定的资源依赖的资源包文件 /// /// 资源信息 + /// 下载资源对象所属资源包内所有资源对象依赖的资源包 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); AssetInfo[] assetInfos = new AssetInfo[] { assetInfo }; - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain, timeout); + } + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + return CreateBundleDownloader(assetInfo, false, downloadingMaxNumber, failedTryAgain, timeout); } /// /// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件 /// /// 资源信息列表 + /// 下载资源对象所属资源包内所有资源对象依赖的资源包 /// 同时下载的最大文件数 /// 下载失败的重试次数 /// 超时时间 - public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) { DebugCheckInitialize(); - return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout); + return _playModeImpl.CreateResourceDownloaderByPaths(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain, timeout); + } + public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60) + { + return CreateBundleDownloader(assetInfos, false, downloadingMaxNumber, failedTryAgain, timeout); } #endregion