216 lines
6.7 KiB
C#
216 lines
6.7 KiB
C#
![]() |
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace YooAsset
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 文件下载器
|
|||
|
/// </summary>
|
|||
|
internal sealed class FileDownloader : DownloaderBase
|
|||
|
{
|
|||
|
private enum ESteps
|
|||
|
{
|
|||
|
None,
|
|||
|
PrepareDownload,
|
|||
|
CreateDownloader,
|
|||
|
CheckDownload,
|
|||
|
VerifyTempFile,
|
|||
|
WaitingVerifyTempFile,
|
|||
|
CachingFile,
|
|||
|
TryAgain,
|
|||
|
Done,
|
|||
|
}
|
|||
|
|
|||
|
private VerifyTempFileOperation _verifyFileOp = null;
|
|||
|
private ESteps _steps = ESteps.None;
|
|||
|
|
|||
|
public FileDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
|
|||
|
{
|
|||
|
}
|
|||
|
public override void SendRequest(params object[] args)
|
|||
|
{
|
|||
|
if (_steps == ESteps.None)
|
|||
|
{
|
|||
|
_steps = ESteps.PrepareDownload;
|
|||
|
}
|
|||
|
}
|
|||
|
public override void Update()
|
|||
|
{
|
|||
|
if (_steps == ESteps.None)
|
|||
|
return;
|
|||
|
if (IsDone())
|
|||
|
return;
|
|||
|
|
|||
|
// 准备下载
|
|||
|
if (_steps == ESteps.PrepareDownload)
|
|||
|
{
|
|||
|
// 获取请求地址
|
|||
|
_requestURL = GetRequestURL();
|
|||
|
|
|||
|
// 重置变量
|
|||
|
DownloadProgress = 0f;
|
|||
|
DownloadedBytes = 0;
|
|||
|
|
|||
|
// 重置变量
|
|||
|
_isAbort = false;
|
|||
|
_latestDownloadBytes = 0;
|
|||
|
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
|||
|
|
|||
|
// 重置计时器
|
|||
|
if (_tryAgainTimer > 0f)
|
|||
|
YooLogger.Warning($"Try again download : {_requestURL}");
|
|||
|
_tryAgainTimer = 0f;
|
|||
|
|
|||
|
_steps = ESteps.CreateDownloader;
|
|||
|
}
|
|||
|
|
|||
|
// 创建下载器
|
|||
|
if (_steps == ESteps.CreateDownloader)
|
|||
|
{
|
|||
|
_requester = (IWebRequester)Activator.CreateInstance(_requesterType);
|
|||
|
_requester.Create(_requestURL, _bundleInfo);
|
|||
|
_steps = ESteps.CheckDownload;
|
|||
|
}
|
|||
|
|
|||
|
// 检测下载结果
|
|||
|
if (_steps == ESteps.CheckDownload)
|
|||
|
{
|
|||
|
_requester.Update();
|
|||
|
DownloadedBytes = _requester.DownloadedBytes;
|
|||
|
DownloadProgress = _requester.DownloadProgress;
|
|||
|
if (_requester.IsDone() == false)
|
|||
|
{
|
|||
|
CheckTimeout();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
_lastestNetError = _requester.RequestNetError;
|
|||
|
_lastestHttpCode = _requester.RequestHttpCode;
|
|||
|
if (_requester.Status != ERequestStatus.Success)
|
|||
|
{
|
|||
|
_steps = ESteps.TryAgain;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.VerifyTempFile;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 验证下载文件
|
|||
|
if (_steps == ESteps.VerifyTempFile)
|
|||
|
{
|
|||
|
VerifyTempFileElement element = new VerifyTempFileElement(_bundleInfo.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize);
|
|||
|
_verifyFileOp = VerifyTempFileOperation.CreateOperation(element);
|
|||
|
OperationSystem.StartOperation(_bundleInfo.Bundle.PackageName, _verifyFileOp);
|
|||
|
_steps = ESteps.WaitingVerifyTempFile;
|
|||
|
}
|
|||
|
|
|||
|
// 等待验证完成
|
|||
|
if (_steps == ESteps.WaitingVerifyTempFile)
|
|||
|
{
|
|||
|
if (WaitForAsyncComplete)
|
|||
|
_verifyFileOp.InternalOnUpdate();
|
|||
|
|
|||
|
if (_verifyFileOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_verifyFileOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.CachingFile;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string tempFilePath = _bundleInfo.TempDataFilePath;
|
|||
|
if (File.Exists(tempFilePath))
|
|||
|
File.Delete(tempFilePath);
|
|||
|
|
|||
|
_lastestNetError = _verifyFileOp.Error;
|
|||
|
_steps = ESteps.TryAgain;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 缓存下载文件
|
|||
|
if (_steps == ESteps.CachingFile)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
CachingFile();
|
|||
|
_status = EStatus.Succeed;
|
|||
|
_steps = ESteps.Done;
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
_lastestNetError = e.Message;
|
|||
|
_steps = ESteps.TryAgain;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 重新尝试下载
|
|||
|
if (_steps == ESteps.TryAgain)
|
|||
|
{
|
|||
|
if (_failedTryAgain <= 0)
|
|||
|
{
|
|||
|
ReportError();
|
|||
|
_status = EStatus.Failed;
|
|||
|
_steps = ESteps.Done;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
_tryAgainTimer += Time.unscaledDeltaTime;
|
|||
|
if (_tryAgainTimer > 1f)
|
|||
|
{
|
|||
|
_failedTryAgain--;
|
|||
|
_steps = ESteps.PrepareDownload;
|
|||
|
ReportWarning();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
public override void Abort()
|
|||
|
{
|
|||
|
if (_requester != null)
|
|||
|
_requester.Abort();
|
|||
|
|
|||
|
if (IsDone() == false)
|
|||
|
{
|
|||
|
_status = EStatus.Failed;
|
|||
|
_steps = ESteps.Done;
|
|||
|
_lastestNetError = "user abort";
|
|||
|
_lastestHttpCode = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
public override AssetBundle GetAssetBundle()
|
|||
|
{
|
|||
|
throw new NotImplementedException();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 缓存下载文件
|
|||
|
/// </summary>
|
|||
|
private void CachingFile()
|
|||
|
{
|
|||
|
string tempFilePath = _bundleInfo.TempDataFilePath;
|
|||
|
string infoFilePath = _bundleInfo.CachedInfoFilePath;
|
|||
|
string dataFilePath = _bundleInfo.CachedDataFilePath;
|
|||
|
string dataFileCRC = _bundleInfo.Bundle.FileCRC;
|
|||
|
long dataFileSize = _bundleInfo.Bundle.FileSize;
|
|||
|
|
|||
|
if (File.Exists(infoFilePath))
|
|||
|
File.Delete(infoFilePath);
|
|||
|
if (File.Exists(dataFilePath))
|
|||
|
File.Delete(dataFilePath);
|
|||
|
|
|||
|
// 移动临时文件路径
|
|||
|
FileInfo fileInfo = new FileInfo(tempFilePath);
|
|||
|
fileInfo.MoveTo(dataFilePath);
|
|||
|
|
|||
|
// 写入信息文件记录验证数据
|
|||
|
CacheHelper.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize);
|
|||
|
|
|||
|
// 记录缓存文件
|
|||
|
_bundleInfo.CacheRecord();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|