mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-26 18:50:10 +00:00
192 lines
6.9 KiB
C#
192 lines
6.9 KiB
C#
using System.IO;
|
|
|
|
namespace YooAsset
|
|
{
|
|
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 DownloadAndCacheLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url) : base(url)
|
|
{
|
|
_fileSystem = fileSystem;
|
|
_bundle = bundle;
|
|
_tempFilePath = _fileSystem.GetTempFilePath(_bundle);
|
|
}
|
|
internal override void InternalStart()
|
|
{
|
|
_steps = ESteps.CheckCopy;
|
|
}
|
|
internal override void InternalUpdate()
|
|
{
|
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
|
return;
|
|
|
|
// 检测文件拷贝
|
|
if (_steps == ESteps.CheckCopy)
|
|
{
|
|
// 删除历史缓存文件
|
|
FileUtility.CreateFileDirectory(_tempFilePath);
|
|
if (File.Exists(_tempFilePath))
|
|
File.Delete(_tempFilePath);
|
|
|
|
if (_fileSystem.CopyLocalFileServices != null)
|
|
_steps = ESteps.CopyLocalFile;
|
|
else
|
|
_steps = ESteps.CreateRequest;
|
|
}
|
|
|
|
// 拷贝本地文件
|
|
if (_steps == ESteps.CopyLocalFile)
|
|
{
|
|
try
|
|
{
|
|
//TODO 团结引擎,在某些机型(红米),拷贝包内文件会小概率失败!需要借助其它方式来拷贝包内文件。
|
|
var localFileInfo = new LocalFileInfo();
|
|
localFileInfo.PackageName = _fileSystem.PackageName;
|
|
localFileInfo.BundleName = _bundle.BundleName;
|
|
localFileInfo.SourceFileURL = URL;
|
|
_fileSystem.CopyLocalFileServices.CopyFile(localFileInfo, _tempFilePath);
|
|
if (File.Exists(_tempFilePath))
|
|
{
|
|
DownloadProgress = 1f;
|
|
DownloadedBytes = _bundle.FileSize;
|
|
_steps = ESteps.VerifyBundleFile;
|
|
}
|
|
else
|
|
{
|
|
_steps = ESteps.Done;
|
|
Status = EOperationStatus.Failed;
|
|
Error = $"Failed copy local file : {URL}";
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
_steps = ESteps.Done;
|
|
Status = EOperationStatus.Failed;
|
|
Error = $"Failed copy local file : {ex.Message}";
|
|
}
|
|
}
|
|
|
|
// 创建下载请求
|
|
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)
|
|
{
|
|
//TODO 更新下载后台,防止无限挂起
|
|
if (IsWaitForAsyncComplete)
|
|
_fileSystem.DownloadBackend.Update();
|
|
|
|
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)
|
|
{
|
|
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.Dispose();
|
|
}
|
|
internal override void InternalWaitForAsyncComplete()
|
|
{
|
|
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
|
|
RunUntilCompletion();
|
|
}
|
|
}
|
|
} |