refactor : 重构网络下载模块
新增通用下载接口,扩展了默认的Unity引擎下载器
This commit is contained in:
+16
-8
@@ -23,10 +23,14 @@ namespace YooAsset
|
||||
protected string _cacheManifestFilesRoot;
|
||||
|
||||
/// <summary>
|
||||
/// 下载中心
|
||||
/// 说明:当异步操作任务终止的时候,所有下载子任务都会一同被终止!
|
||||
/// 下载调度器
|
||||
/// </summary>
|
||||
public DownloadCenterOperation DownloadCenter { set; get; }
|
||||
public DownloadSchedulerOperation DownloadScheduler { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 下载后台接口
|
||||
/// </summary>
|
||||
public IDownloadBackend DownloadBackend { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 包裹名称
|
||||
@@ -105,7 +109,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 自定义参数:下载任务的看门狗机制监控时间
|
||||
/// </summary>
|
||||
public int DownloadWatchDogTime { private set; get; } = int.MaxValue;
|
||||
public int DownloadWatchDogTime { private set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:启用断点续传的最小尺寸
|
||||
@@ -288,7 +292,7 @@ namespace YooAsset
|
||||
else if (name == FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME)
|
||||
{
|
||||
int convertValue = Convert.ToInt32(value);
|
||||
DownloadWatchDogTime = Mathf.Clamp(convertValue, 1, int.MaxValue);
|
||||
DownloadWatchDogTime = Mathf.Clamp(convertValue, 0, int.MaxValue);
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
|
||||
{
|
||||
@@ -327,13 +331,17 @@ namespace YooAsset
|
||||
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
|
||||
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
|
||||
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
|
||||
|
||||
// 创建默认的下载后台接口
|
||||
if (DownloadBackend == null)
|
||||
DownloadBackend = new UnityWebRequestBackend(DownloadSystemHelper.UnityWebRequestCreater);
|
||||
}
|
||||
public virtual void OnDestroy()
|
||||
{
|
||||
if (DownloadCenter != null)
|
||||
if (DownloadScheduler != null)
|
||||
{
|
||||
DownloadCenter.AbortOperation();
|
||||
DownloadCenter = null;
|
||||
DownloadScheduler.Dispose();
|
||||
DownloadScheduler = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -9,7 +9,7 @@ namespace YooAsset
|
||||
CheckAppFootPrint,
|
||||
SearchCacheFiles,
|
||||
VerifyCacheFiles,
|
||||
CreateDownloadCenter,
|
||||
CreateDownloadScheduler,
|
||||
Done,
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace YooAsset
|
||||
|
||||
if (_verifyCacheFilesOp.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.CreateDownloadCenter;
|
||||
_steps = ESteps.CreateDownloadScheduler;
|
||||
YooLogger.Log($"Package '{_fileSystem.PackageName}' '{_fileSystem.GetType().Name}' cached files count : {_fileSystem.FileCount}");
|
||||
}
|
||||
else
|
||||
@@ -121,13 +121,13 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CreateDownloadCenter)
|
||||
if (_steps == ESteps.CreateDownloadScheduler)
|
||||
{
|
||||
// 注意:下载中心作为独立任务运行!
|
||||
if (_fileSystem.DownloadCenter == null)
|
||||
if (_fileSystem.DownloadScheduler == null)
|
||||
{
|
||||
_fileSystem.DownloadCenter = new DownloadCenterOperation(_fileSystem);
|
||||
OperationSystem.StartOperation(_fileSystem.PackageName, _fileSystem.DownloadCenter);
|
||||
_fileSystem.DownloadScheduler = new DownloadSchedulerOperation(_fileSystem);
|
||||
OperationSystem.StartOperation(_fileSystem.PackageName, _fileSystem.DownloadScheduler);
|
||||
}
|
||||
|
||||
_steps = ESteps.Done;
|
||||
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class DownloadCenterOperation : AsyncOperationBase
|
||||
{
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly Dictionary<string, UnityDownloadFileOperation> _downloaders = new Dictionary<string, UnityDownloadFileOperation>(1000);
|
||||
protected readonly List<string> _removeList = new List<string>(1000);
|
||||
|
||||
public DownloadCenterOperation(DefaultCacheFileSystem fileSystem)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
// 获取可移除的下载器集合
|
||||
_removeList.Clear();
|
||||
foreach (var valuePair in _downloaders)
|
||||
{
|
||||
var downloader = valuePair.Value;
|
||||
downloader.UpdateOperation();
|
||||
if (downloader.IsDone)
|
||||
{
|
||||
_removeList.Add(valuePair.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 注意:主动终止引用计数为零的下载任务
|
||||
if (downloader.RefCount <= 0)
|
||||
{
|
||||
_removeList.Add(valuePair.Key);
|
||||
downloader.AbortOperation();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除下载器
|
||||
foreach (var key in _removeList)
|
||||
{
|
||||
if (_downloaders.TryGetValue(key, out var downloader))
|
||||
{
|
||||
Childs.Remove(downloader);
|
||||
_downloaders.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 最大并发数检测
|
||||
int processCount = GetProcessingOperationCount();
|
||||
if (processCount != _downloaders.Count)
|
||||
{
|
||||
if (processCount < _fileSystem.DownloadMaxConcurrency)
|
||||
{
|
||||
int startCount = _fileSystem.DownloadMaxConcurrency - processCount;
|
||||
if (startCount > _fileSystem.DownloadMaxRequestPerFrame)
|
||||
startCount = _fileSystem.DownloadMaxRequestPerFrame;
|
||||
|
||||
foreach (var operationPair in _downloaders)
|
||||
{
|
||||
var operation = operationPair.Value;
|
||||
if (operation.Status == EOperationStatus.None)
|
||||
{
|
||||
operation.StartOperation();
|
||||
startCount--;
|
||||
if (startCount <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建下载任务
|
||||
/// </summary>
|
||||
public UnityDownloadFileOperation DownloadFileAsync(PackageBundle bundle, string url)
|
||||
{
|
||||
// 查询旧的下载器
|
||||
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
|
||||
{
|
||||
oldDownloader.Reference();
|
||||
return oldDownloader;
|
||||
}
|
||||
|
||||
// 创建新的下载器
|
||||
UnityDownloadFileOperation newDownloader;
|
||||
bool isRequestLocalFile = DownloadSystemHelper.IsRequestLocalFile(url);
|
||||
if (isRequestLocalFile)
|
||||
{
|
||||
newDownloader = new UnityDownloadLocalFileOperation(_fileSystem, bundle, url);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
|
||||
{
|
||||
newDownloader = new UnityDownloadResumeFileOperation(_fileSystem, bundle, url);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
else
|
||||
{
|
||||
newDownloader = new UnityDownloadNormalFileOperation(_fileSystem, bundle, url);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
}
|
||||
|
||||
newDownloader.Reference();
|
||||
return newDownloader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取正在进行中的下载器总数
|
||||
/// </summary>
|
||||
private int GetProcessingOperationCount()
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var operationPair in _downloaders)
|
||||
{
|
||||
var operation = operationPair.Value;
|
||||
if (operation.Status != EOperationStatus.None)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-18
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace YooAsset
|
||||
// 下载参数
|
||||
protected readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly DownloadFileOptions _options;
|
||||
private UnityDownloadFileOperation _unityDownloadFileOp;
|
||||
private DownloadAndCacheFileOperation _downloadFileOp;
|
||||
|
||||
protected int _requestCount = 0;
|
||||
protected float _tryAgainTimer = 0;
|
||||
@@ -67,7 +68,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
string url = GetRequestURL();
|
||||
_unityDownloadFileOp = _fileSystem.DownloadCenter.DownloadFileAsync(Bundle, url);
|
||||
_downloadFileOp = _fileSystem.DownloadScheduler.DownloadAndCacheFileAsync(Bundle, url);
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
|
||||
@@ -75,20 +76,16 @@ namespace YooAsset
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
_unityDownloadFileOp.WaitForAsyncComplete();
|
||||
_downloadFileOp.WaitForAsyncComplete();
|
||||
|
||||
// 因为并发数量限制,下载器可能被挂起!
|
||||
if (_unityDownloadFileOp.Status == EOperationStatus.None)
|
||||
_downloadFileOp.UpdateOperation();
|
||||
Progress = _downloadFileOp.Progress;
|
||||
DownloadedBytes = _downloadFileOp.DownloadedBytes;
|
||||
DownloadProgress = _downloadFileOp.DownloadProgress;
|
||||
if (_downloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
_unityDownloadFileOp.UpdateOperation();
|
||||
Progress = _unityDownloadFileOp.Progress;
|
||||
DownloadedBytes = _unityDownloadFileOp.DownloadedBytes;
|
||||
DownloadProgress = _unityDownloadFileOp.DownloadProgress;
|
||||
if (_unityDownloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_unityDownloadFileOp.Status == EOperationStatus.Succeed)
|
||||
if (_downloadFileOp.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
@@ -98,13 +95,13 @@ namespace YooAsset
|
||||
if (IsWaitForAsyncComplete == false && _failedTryAgain > 0)
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
YooLogger.Warning($"Failed download : {_unityDownloadFileOp.URL} Try again !");
|
||||
YooLogger.Warning($"Failed download : {_downloadFileOp.URL} Try again !");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unityDownloadFileOp.Error;
|
||||
Error = _downloadFileOp.Error;
|
||||
YooLogger.Error(Error);
|
||||
}
|
||||
}
|
||||
@@ -141,9 +138,9 @@ namespace YooAsset
|
||||
// 注意:取消下载任务的时候引用计数减一
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
if (_unityDownloadFileOp != null)
|
||||
if (_downloadFileOp != null)
|
||||
{
|
||||
_unityDownloadFileOp.Release();
|
||||
_downloadFileOp.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -15,7 +15,7 @@ namespace YooAsset
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly string _packageVersion;
|
||||
private readonly int _timeout;
|
||||
private UnityWebFileRequestOperation _webFileRequestOp;
|
||||
private IDownloadFileRequest _webFileRequestOp;
|
||||
private int _requestCount = 0;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
@@ -57,16 +57,16 @@ namespace YooAsset
|
||||
string savePath = _fileSystem.GetCachePackageHashFilePath(_packageVersion);
|
||||
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
|
||||
string webURL = GetWebRequestURL(fileName);
|
||||
_webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout);
|
||||
_webFileRequestOp.StartOperation();
|
||||
AddChildOperation(_webFileRequestOp);
|
||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
||||
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
||||
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
_webFileRequestOp.SendRequest();
|
||||
}
|
||||
|
||||
_webFileRequestOp.UpdateOperation();
|
||||
if (_webFileRequestOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_webFileRequestOp.Status == EOperationStatus.Succeed)
|
||||
if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
|
||||
+6
-6
@@ -15,7 +15,7 @@ namespace YooAsset
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly string _packageVersion;
|
||||
private readonly int _timeout;
|
||||
private UnityWebFileRequestOperation _webFileRequestOp;
|
||||
private IDownloadFileRequest _webFileRequestOp;
|
||||
private int _requestCount = 0;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
@@ -57,16 +57,16 @@ namespace YooAsset
|
||||
string savePath = _fileSystem.GetCachePackageManifestFilePath(_packageVersion);
|
||||
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
|
||||
string webURL = GetDownloadRequestURL(fileName);
|
||||
_webFileRequestOp = new UnityWebFileRequestOperation(webURL, savePath, _timeout);
|
||||
_webFileRequestOp.StartOperation();
|
||||
AddChildOperation(_webFileRequestOp);
|
||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
||||
var args = new DownloadFileRequestArgs(webURL, savePath, _timeout, watchdogTime);
|
||||
_webFileRequestOp = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
_webFileRequestOp.SendRequest();
|
||||
}
|
||||
|
||||
_webFileRequestOp.UpdateOperation();
|
||||
if (_webFileRequestOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_webFileRequestOp.Status == EOperationStatus.Succeed)
|
||||
if (_webFileRequestOp.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
|
||||
+7
-7
@@ -13,7 +13,7 @@ namespace YooAsset
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly bool _appendTimeTicks;
|
||||
private readonly int _timeout;
|
||||
private UnityWebTextRequestOperation _webTextRequestOp;
|
||||
private IDownloadTextRequest _webTextRequestOp;
|
||||
private int _requestCount = 0;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
@@ -45,17 +45,17 @@ namespace YooAsset
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
|
||||
string url = GetWebRequestURL(fileName);
|
||||
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
|
||||
_webTextRequestOp.StartOperation();
|
||||
AddChildOperation(_webTextRequestOp);
|
||||
int watchDogTime = _fileSystem.DownloadWatchDogTime;
|
||||
var args = new DownloadDataRequestArgs(url, _timeout, watchDogTime);
|
||||
_webTextRequestOp = _fileSystem.DownloadBackend.CreateTextRequest(args);
|
||||
_webTextRequestOp.SendRequest();
|
||||
}
|
||||
|
||||
_webTextRequestOp.UpdateOperation();
|
||||
Progress = _webTextRequestOp.Progress;
|
||||
Progress = _webTextRequestOp.DownloadProgress;
|
||||
if (_webTextRequestOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_webTextRequestOp.Status == EOperationStatus.Succeed)
|
||||
if (_webTextRequestOp.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
PackageVersion = _webTextRequestOp.Result;
|
||||
if (string.IsNullOrEmpty(PackageVersion))
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf9991076b60f0f459846f54b0ca6698
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class DownloadAndCacheFileOperation : AsyncOperationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
public int RefCount { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 下载地址
|
||||
/// </summary>
|
||||
public readonly string URL;
|
||||
|
||||
/// <summary>
|
||||
/// 下载进度
|
||||
/// </summary>
|
||||
public float DownloadProgress { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下载字节
|
||||
/// </summary>
|
||||
public long DownloadedBytes { get; protected set; }
|
||||
|
||||
public DownloadAndCacheFileOperation(string url)
|
||||
{
|
||||
URL = url;
|
||||
}
|
||||
internal override string InternalGetDesc()
|
||||
{
|
||||
return $"RefCount : {RefCount}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减少引用计数
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
RefCount--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数
|
||||
/// </summary>
|
||||
public void Reference()
|
||||
{
|
||||
RefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c68640bb1d36552469024324e3357bc2
|
||||
guid: 2954a64fd419d5a4b9d0a102260d193c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
+98
-71
@@ -1,94 +1,79 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class UnityDownloadLocalFileOperation : UnityDownloadFileOperation
|
||||
internal sealed class DownloadAndCacheLocalFileOperation : DownloadAndCacheFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckCopy,
|
||||
CopyLocalFile,
|
||||
CreateRequest,
|
||||
CheckRequest,
|
||||
VerifyBundleFile,
|
||||
CacheBundleFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly PackageBundle _bundle;
|
||||
private readonly string _tempFilePath;
|
||||
private IDownloadRequest _request;
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal UnityDownloadLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url)
|
||||
: base(fileSystem, bundle, url)
|
||||
internal DownloadAndCacheLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_bundle = bundle;
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(_bundle);
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
if (_fileSystem.CopyLocalFileServices != null)
|
||||
_steps = ESteps.CopyLocalFile;
|
||||
else
|
||||
_steps = ESteps.CreateRequest;
|
||||
_steps = ESteps.CheckCopy;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
// 检测文件拷贝
|
||||
if (_steps == ESteps.CheckCopy)
|
||||
{
|
||||
// 删除历史缓存文件
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
|
||||
UpdateWatchDog();
|
||||
if (_webRequest.isDone == false)
|
||||
return;
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
if (_fileSystem.CopyLocalFileServices != null)
|
||||
_steps = ESteps.CopyLocalFile;
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeRequest();
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
|
||||
// 拷贝内置文件
|
||||
// 拷贝本地文件
|
||||
if (_steps == ESteps.CopyLocalFile)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
try
|
||||
{
|
||||
//TODO 团结引擎,在某些机型(红米),拷贝包内文件会小概率失败!需要借助其它方式来拷贝包内文件。
|
||||
var localFileInfo = new LocalFileInfo();
|
||||
localFileInfo.PackageName = _fileSystem.PackageName;
|
||||
localFileInfo.BundleName = _bundle.BundleName;
|
||||
localFileInfo.SourceFileURL = _requestURL;
|
||||
localFileInfo.SourceFileURL = URL;
|
||||
_fileSystem.CopyLocalFileServices.CopyFile(localFileInfo, _tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
DownloadProgress = 1f;
|
||||
DownloadedBytes = _bundle.FileSize;
|
||||
Progress = DownloadProgress;
|
||||
_steps = ESteps.VerifyFile;
|
||||
_steps = ESteps.VerifyBundleFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Failed copy local file : {_requestURL}";
|
||||
Error = $"Failed copy local file : {URL}";
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
@@ -99,8 +84,44 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
// 创建下载请求
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
||||
int timeout = 0; //注意:文件下载不做超时检测
|
||||
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
||||
_request = _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
_request.SendRequest();
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
{
|
||||
DownloadProgress = _request.DownloadProgress;
|
||||
DownloadedBytes = _request.DownloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
if (_request.IsDone == false)
|
||||
return;
|
||||
|
||||
// 检查网络错误
|
||||
if (_request.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.VerifyBundleFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _request.Error;
|
||||
}
|
||||
|
||||
// 最终释放请求器
|
||||
_request.Dispose();
|
||||
}
|
||||
|
||||
// 验证下载结果
|
||||
if (_steps == ESteps.VerifyBundleFile)
|
||||
{
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
@@ -119,35 +140,51 @@ namespace YooAsset
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
}
|
||||
_steps = ESteps.CacheBundleFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
|
||||
// 注意:验证失败后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存文件
|
||||
if (_steps == ESteps.CacheBundleFile)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
}
|
||||
|
||||
// 注意:验证完成后直接删除文件
|
||||
// 注意:缓存完成后直接删除临时文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
if (_request != null)
|
||||
_request.AbortRequest();
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
|
||||
_fileSystem.DownloadBackend.Update();
|
||||
InternalUpdate();
|
||||
if (IsDone)
|
||||
break;
|
||||
@@ -156,15 +193,5 @@ namespace YooAsset
|
||||
System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 768ef2df3433df245a26fec28d022e45
|
||||
guid: 47700ac672942834f8d5a7c59783d88e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class DownloadAndCacheRemoteFileOperation : DownloadAndCacheFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
CheckRequest,
|
||||
VerifyBundleFile,
|
||||
CacheBundleFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly PackageBundle _bundle;
|
||||
private readonly string _tempFilePath;
|
||||
private bool _enableResume = false;
|
||||
private long _fileOriginLength = 0;
|
||||
private IDownloadRequest _request;
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal DownloadAndCacheRemoteFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_bundle = bundle;
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(_bundle);
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 创建下载请求
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
|
||||
_enableResume = _bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize;
|
||||
if (_enableResume)
|
||||
{
|
||||
_request = CreateResumeRequest();
|
||||
_request.SendRequest();
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
_request = CreateNormalRequest();
|
||||
_request.SendRequest();
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
{
|
||||
DownloadProgress = _request.DownloadProgress;
|
||||
DownloadedBytes = _fileOriginLength + _request.DownloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
if (_request.IsDone == false)
|
||||
return;
|
||||
|
||||
// 检查网络错误
|
||||
if (_request.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.VerifyBundleFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _request.Error;
|
||||
}
|
||||
|
||||
// 在遇到特殊错误的时候删除文件
|
||||
if (_enableResume)
|
||||
ClearTempFileWhenError(_request.HttpCode);
|
||||
|
||||
// 最终释放请求器
|
||||
_request.Dispose();
|
||||
}
|
||||
|
||||
// 验证下载结果
|
||||
if (_steps == ESteps.VerifyBundleFile)
|
||||
{
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
if (IsWaitForAsyncComplete)
|
||||
_verifyOperation.WaitForAsyncComplete();
|
||||
|
||||
_verifyOperation.UpdateOperation();
|
||||
if (_verifyOperation.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.CacheBundleFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
|
||||
// 注意:验证失败后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存文件
|
||||
if (_steps == ESteps.CacheBundleFile)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
}
|
||||
|
||||
// 注意:缓存完成后直接删除临时文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
if (_request != null)
|
||||
_request.AbortRequest();
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
// 注意:不中断下载任务,保持后台继续下载
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {URL} !");
|
||||
}
|
||||
}
|
||||
|
||||
private IDownloadRequest CreateResumeRequest()
|
||||
{
|
||||
// 获取下载起始位置
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
if (fileInfo.Length >= _bundle.FileSize)
|
||||
{
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileOriginLength = fileInfo.Length;
|
||||
}
|
||||
}
|
||||
|
||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
||||
int timeout = 0; //注意:文件下载不做超时检测
|
||||
bool appendToFile = true;
|
||||
bool removeFileOnAbort = false;
|
||||
long resumeFromBytes = _fileOriginLength;
|
||||
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime, appendToFile, removeFileOnAbort, resumeFromBytes);
|
||||
return _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
}
|
||||
private IDownloadRequest CreateNormalRequest()
|
||||
{
|
||||
// 删除历史缓存文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
int watchdogTime = _fileSystem.DownloadWatchDogTime;
|
||||
int timeout = 0; //注意:文件下载不做超时检测
|
||||
var args = new DownloadFileRequestArgs(URL, _tempFilePath, timeout, watchdogTime);
|
||||
return _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
}
|
||||
private void ClearTempFileWhenError(long httpCode)
|
||||
{
|
||||
if (_fileSystem.ResumeDownloadResponseCodes == null)
|
||||
return;
|
||||
|
||||
//说明:如果遇到以下错误返回码,验证失败直接删除文件
|
||||
if (_fileSystem.ResumeDownloadResponseCodes.Contains(httpCode))
|
||||
{
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 759967d543776a0469b625eff171d235
|
||||
guid: ad910a81855976e44b4f1f09051910b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载调度器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 管理所有活跃的下载任务,控制并发数量。
|
||||
/// </remarks>
|
||||
internal class DownloadSchedulerOperation : AsyncOperationBase, IDisposable
|
||||
{
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private readonly Dictionary<string, DownloadAndCacheFileOperation> _downloaders = new Dictionary<string, DownloadAndCacheFileOperation>(1000);
|
||||
private readonly List<string> _removeList = new List<string>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// 是否已暂停
|
||||
/// </summary>
|
||||
public bool Paused { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前活跃的下载任务数
|
||||
/// </summary>
|
||||
public int ActiveDownloadCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前等待中的下载任务数
|
||||
/// </summary>
|
||||
public int PendingDownloadCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _downloaders.Count - ActiveDownloadCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造下载中心
|
||||
/// </summary>
|
||||
public DownloadSchedulerOperation(DefaultCacheFileSystem fileSystem)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
// 驱动下载后台
|
||||
_fileSystem.DownloadBackend.Update();
|
||||
|
||||
// 获取可移除的下载器集合
|
||||
_removeList.Clear();
|
||||
foreach (var valuePair in _downloaders)
|
||||
{
|
||||
var downloader = valuePair.Value;
|
||||
downloader.UpdateOperation();
|
||||
if (downloader.IsDone)
|
||||
{
|
||||
_removeList.Add(valuePair.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 注意:主动终止引用计数为零的下载任务
|
||||
if (downloader.RefCount <= 0)
|
||||
{
|
||||
_removeList.Add(valuePair.Key);
|
||||
downloader.AbortOperation();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除下载器
|
||||
foreach (var key in _removeList)
|
||||
{
|
||||
if (_downloaders.TryGetValue(key, out var downloader))
|
||||
{
|
||||
RemoveChildOperation(downloader);
|
||||
_downloaders.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 暂停时不启动新任务
|
||||
if (Paused)
|
||||
return;
|
||||
|
||||
// 最大并发数检测
|
||||
ActiveDownloadCount = GetProcessingOperationCount();
|
||||
if (ActiveDownloadCount != _downloaders.Count)
|
||||
{
|
||||
int maxConcurrency = _fileSystem.DownloadMaxConcurrency;
|
||||
int maxRequestPerFrame = _fileSystem.DownloadMaxRequestPerFrame;
|
||||
if (ActiveDownloadCount < maxConcurrency)
|
||||
{
|
||||
int startCount = maxConcurrency - ActiveDownloadCount;
|
||||
if (startCount > maxRequestPerFrame)
|
||||
startCount = maxRequestPerFrame;
|
||||
|
||||
foreach (var operationPair in _downloaders)
|
||||
{
|
||||
var operation = operationPair.Value;
|
||||
if (operation.Status == EOperationStatus.None)
|
||||
{
|
||||
operation.StartOperation();
|
||||
startCount--;
|
||||
if (startCount <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中止所有下载任务
|
||||
/// </summary>
|
||||
public void AbortAll()
|
||||
{
|
||||
foreach (var valuePair in _downloaders)
|
||||
{
|
||||
valuePair.Value.AbortOperation();
|
||||
}
|
||||
_downloaders.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
AbortAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建下载任务
|
||||
/// </summary>
|
||||
/// <param name="bundle">资源包信息</param>
|
||||
/// <param name="url">下载地址</param>
|
||||
/// <returns>下载操作</returns>
|
||||
public DownloadAndCacheFileOperation DownloadAndCacheFileAsync(PackageBundle bundle, string url)
|
||||
{
|
||||
// 查询旧的下载器
|
||||
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
|
||||
{
|
||||
oldDownloader.Reference();
|
||||
return oldDownloader;
|
||||
}
|
||||
|
||||
// 创建新的下载器
|
||||
DownloadAndCacheFileOperation newDownloader;
|
||||
bool isRequestLocalFile = DownloadSystemHelper.IsRequestLocalFile(url);
|
||||
if (isRequestLocalFile)
|
||||
{
|
||||
newDownloader = new DownloadAndCacheLocalFileOperation(_fileSystem, bundle, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
newDownloader = new DownloadAndCacheRemoteFileOperation(_fileSystem, bundle, url);
|
||||
}
|
||||
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
newDownloader.Reference();
|
||||
return newDownloader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取正在进行中的下载器总数
|
||||
/// </summary>
|
||||
private int GetProcessingOperationCount()
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var operationPair in _downloaders)
|
||||
{
|
||||
var operation = operationPair.Value;
|
||||
if (operation.Status != EOperationStatus.None)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40bb5e9391f413c42ae70e48ca90c4b7
|
||||
guid: 73441e829c36a36418f5d677e189e9f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class UnityDownloadFileOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
CopyLocalFile,
|
||||
VerifyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
protected readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly PackageBundle _bundle;
|
||||
protected readonly string _tempFilePath;
|
||||
|
||||
private bool _watchDogInit = false;
|
||||
private bool _watchDogAborted = false;
|
||||
private ulong _lastDownloadBytes;
|
||||
private double _lastGetDataTime;
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
public int RefCount { private set; get; }
|
||||
|
||||
internal UnityDownloadFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_bundle = bundle;
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(bundle);
|
||||
}
|
||||
internal override string InternalGetDesc()
|
||||
{
|
||||
return $"RefCount : {RefCount}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新看门狗监测
|
||||
/// 说明:监控时间范围内,如果没有接收到任何下载数据,那么直接终止任务!
|
||||
/// </summary>
|
||||
protected void UpdateWatchDog()
|
||||
{
|
||||
if (_fileSystem.DownloadWatchDogTime == int.MaxValue)
|
||||
return;
|
||||
|
||||
if (_watchDogAborted)
|
||||
return;
|
||||
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartupAsDouble;
|
||||
#else
|
||||
double realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartup;
|
||||
#endif
|
||||
|
||||
if (_watchDogInit == false)
|
||||
{
|
||||
_watchDogInit = true;
|
||||
_lastDownloadBytes = 0;
|
||||
_lastGetDataTime = realtimeSinceStartup;
|
||||
}
|
||||
|
||||
if (_webRequest.downloadedBytes != _lastDownloadBytes)
|
||||
{
|
||||
_lastDownloadBytes = _webRequest.downloadedBytes;
|
||||
_lastGetDataTime = realtimeSinceStartup;
|
||||
}
|
||||
else
|
||||
{
|
||||
double deltaTime = realtimeSinceStartup - _lastGetDataTime;
|
||||
if (deltaTime > _fileSystem.DownloadWatchDogTime)
|
||||
{
|
||||
_watchDogAborted = true;
|
||||
InternalAbort(); //终止网络请求
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减少引用计数
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
RefCount--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数
|
||||
/// </summary>
|
||||
public void Reference()
|
||||
{
|
||||
RefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class UnityDownloadNormalFileOperation : UnityDownloadFileOperation
|
||||
{
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal UnityDownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url)
|
||||
: base(fileSystem, bundle, url)
|
||||
{
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
|
||||
UpdateWatchDog();
|
||||
if (_webRequest.isDone == false)
|
||||
return;
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
{
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
if (IsWaitForAsyncComplete)
|
||||
_verifyOperation.WaitForAsyncComplete();
|
||||
|
||||
_verifyOperation.UpdateOperation();
|
||||
if (_verifyOperation.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file ! {_tempFilePath}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
}
|
||||
|
||||
// 注意:验证完成后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {_requestURL} !");
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class UnityDownloadResumeFileOperation : UnityDownloadFileOperation
|
||||
{
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private long _fileOriginLength = 0;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal UnityDownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url)
|
||||
: base(fileSystem, bundle, url)
|
||||
{
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
|
||||
// 获取下载起始位置
|
||||
_fileOriginLength = 0;
|
||||
long fileBeginLength = -1;
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
if (fileInfo.Length >= _bundle.FileSize)
|
||||
{
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileBeginLength = fileInfo.Length;
|
||||
_fileOriginLength = fileBeginLength;
|
||||
DownloadedBytes = _fileOriginLength;
|
||||
}
|
||||
}
|
||||
|
||||
CreateWebRequest(fileBeginLength);
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = _fileOriginLength + (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
|
||||
UpdateWatchDog();
|
||||
if (_webRequest.isDone == false)
|
||||
return;
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 在遇到特殊错误的时候删除文件
|
||||
ClearTempFileWhenError();
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
{
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
if (IsWaitForAsyncComplete)
|
||||
_verifyOperation.WaitForAsyncComplete();
|
||||
|
||||
_verifyOperation.UpdateOperation();
|
||||
if (_verifyOperation.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
}
|
||||
|
||||
// 注意:验证完成后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {_requestURL} !");
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearTempFileWhenError()
|
||||
{
|
||||
if (_fileSystem.ResumeDownloadResponseCodes == null)
|
||||
return;
|
||||
|
||||
//说明:如果遇到以下错误返回码,验证失败直接删除文件
|
||||
if (_fileSystem.ResumeDownloadResponseCodes.Contains(HttpCode))
|
||||
{
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
private void CreateWebRequest(long fileBeginLength)
|
||||
{
|
||||
var handler = new DownloadHandlerFile(_tempFilePath, true);
|
||||
handler.removeFileOnAbort = false;
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
if (fileBeginLength > 0)
|
||||
_webRequest.SetRequestHeader("Range", $"bytes={fileBeginLength}-");
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bfb785912326f942a31dc77762eb16a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user