Add package update method
新增指定资源版本的资源更新下载方法。
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public abstract class UpdatePackageOperation : AsyncOperationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始下载
|
||||
/// </summary>
|
||||
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
|
||||
/// <param name="failedTryAgain">下载失败的重试次数</param>
|
||||
public abstract PackageDownloaderOperation BeginDownloadPackage(int downloadingMaxNumber, int failedTryAgain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的更新资源包裹操作
|
||||
/// </summary>
|
||||
internal sealed class EditorPlayModeUpdatePackageOperation : UpdatePackageOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始下载
|
||||
/// </summary>
|
||||
public override PackageDownloaderOperation BeginDownloadPackage(int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PackageDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
|
||||
operation.BeginDownload();
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离线模式的更新资源包裹操作
|
||||
/// </summary>
|
||||
internal sealed class OfflinePlayModeUpdatePackageOperation : UpdatePackageOperation
|
||||
{
|
||||
internal override void Start()
|
||||
{
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始下载
|
||||
/// </summary>
|
||||
public override PackageDownloaderOperation BeginDownloadPackage(int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PackageDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
|
||||
operation.BeginDownload();
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络模式的更新资源包裹操作
|
||||
/// </summary>
|
||||
internal sealed class HostPlayModeUpdatePackageOperation : UpdatePackageOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
LoadWebManifest,
|
||||
CheckWebManifest,
|
||||
Done,
|
||||
}
|
||||
|
||||
private static int RequestCount = 0;
|
||||
private readonly HostPlayModeImpl _impl;
|
||||
private readonly int _resourceVersion;
|
||||
private readonly int _timeout;
|
||||
private ESteps _steps = ESteps.None;
|
||||
private UnityWebDataRequester _downloaderManifest;
|
||||
private PatchManifest _remotePatchManifest;
|
||||
|
||||
internal HostPlayModeUpdatePackageOperation(HostPlayModeImpl impl, int resourceVersion, int timeout)
|
||||
{
|
||||
_impl = impl;
|
||||
_resourceVersion = resourceVersion;
|
||||
_timeout = timeout;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
RequestCount++;
|
||||
_steps = ESteps.LoadWebManifest;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.LoadWebManifest)
|
||||
{
|
||||
string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestFileName(_resourceVersion));
|
||||
YooLogger.Log($"Beginning to request patch manifest : {webURL}");
|
||||
_downloaderManifest = new UnityWebDataRequester();
|
||||
_downloaderManifest.SendRequest(webURL, _timeout);
|
||||
_steps = ESteps.CheckWebManifest;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CheckWebManifest)
|
||||
{
|
||||
if (_downloaderManifest.IsDone() == false)
|
||||
return;
|
||||
|
||||
// Check error
|
||||
if (_downloaderManifest.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _downloaderManifest.GetError();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 解析补丁清单
|
||||
if (ParseRemotePatchManifest(_downloaderManifest.GetText()))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"URL : {_downloaderManifest.URL} Error : remote patch manifest content is invalid";
|
||||
}
|
||||
}
|
||||
_downloaderManifest.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始下载
|
||||
/// </summary>
|
||||
public override PackageDownloaderOperation BeginDownloadPackage(int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
if (Status == EOperationStatus.Succeed)
|
||||
{
|
||||
List<BundleInfo> downloadList = GetDownloadList();
|
||||
var operation = new PackageDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
|
||||
operation.BeginDownload();
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Error($"{nameof(UpdatePackageOperation)} status is failed !");
|
||||
var operation = new PackageDownloaderOperation(null, downloadingMaxNumber, failedTryAgain);
|
||||
operation.BeginDownload();
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取补丁清单请求地址
|
||||
/// </summary>
|
||||
private string GetPatchManifestRequestURL(string fileName)
|
||||
{
|
||||
// 轮流返回请求地址
|
||||
if (RequestCount % 2 == 0)
|
||||
return _impl.GetPatchDownloadFallbackURL(fileName);
|
||||
else
|
||||
return _impl.GetPatchDownloadMainURL(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析远端请求的补丁清单
|
||||
/// </summary>
|
||||
private bool ParseRemotePatchManifest(string content)
|
||||
{
|
||||
try
|
||||
{
|
||||
_remotePatchManifest = PatchManifest.Deserialize(content);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
YooLogger.Warning(e.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载列表
|
||||
/// </summary>
|
||||
private List<BundleInfo> GetDownloadList()
|
||||
{
|
||||
List<PatchBundle> downloadList = new List<PatchBundle>(1000);
|
||||
foreach (var patchBundle in _remotePatchManifest.BundleList)
|
||||
{
|
||||
// 忽略缓存文件
|
||||
if (DownloadSystem.ContainsVerifyFile(patchBundle.Hash))
|
||||
continue;
|
||||
|
||||
// 忽略APP资源
|
||||
// 注意:如果是APP资源并且哈希值相同,则不需要下载
|
||||
if (_impl.AppPatchManifest.Bundles.TryGetValue(patchBundle.BundleName, out PatchBundle appPatchBundle))
|
||||
{
|
||||
if (appPatchBundle.IsBuildin && appPatchBundle.Hash == patchBundle.Hash)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 注意:下载系统只会验证当前游戏版本的资源文件,对于其它游戏版本的差异文件不会在初始化的时候去做校验。
|
||||
// 注意:通过比对文件大小做实时的文件校验方式!
|
||||
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
long fileSize = FileUtility.GetFileSize(filePath);
|
||||
if (fileSize == patchBundle.SizeBytes)
|
||||
continue;
|
||||
}
|
||||
|
||||
downloadList.Add(patchBundle);
|
||||
}
|
||||
|
||||
return _impl.ConvertToDownloadList(downloadList);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user