Update PatchSystem

pull/51/head
hevinci 2022-10-27 14:20:05 +08:00
parent c1192b37c6
commit 2599639aeb
4 changed files with 285 additions and 105 deletions

View File

@ -114,7 +114,8 @@ namespace YooAsset
initializeParameters.LocationToLower, initializeParameters.LocationToLower,
initializeParameters.DefaultHostServer, initializeParameters.DefaultHostServer,
initializeParameters.FallbackHostServer, initializeParameters.FallbackHostServer,
initializeParameters.QueryServices); initializeParameters.QueryServices,
PackageName);
} }
else else
{ {

View File

@ -67,6 +67,7 @@ namespace YooAsset
private enum ESteps private enum ESteps
{ {
None, None,
QueryPackageVersion,
LoadAppManifest, LoadAppManifest,
InitVerifyingCache, InitVerifyingCache,
UpdateVerifyingCache, UpdateVerifyingCache,
@ -74,15 +75,18 @@ namespace YooAsset
} }
private readonly OfflinePlayModeImpl _impl; private readonly OfflinePlayModeImpl _impl;
private readonly AppManifestLoader _appManifestLoader; private readonly string _packageName;
private readonly CacheVerifier _patchCacheVerifier; private readonly CacheVerifier _patchCacheVerifier;
private readonly AppPackageVersionQuerier _appPackageVersionQuerier;
private AppManifestLoader _appManifestLoader;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
private float _verifyTime; private float _verifyTime;
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string buildinPackageName) internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string packageName)
{ {
_impl = impl; _impl = impl;
_appManifestLoader = new AppManifestLoader(buildinPackageName); _packageName = packageName;
_appPackageVersionQuerier = new AppPackageVersionQuerier(packageName);
#if UNITY_WEBGL #if UNITY_WEBGL
_patchCacheVerifier = new CacheVerifierWithoutThread(); _patchCacheVerifier = new CacheVerifierWithoutThread();
@ -92,21 +96,41 @@ namespace YooAsset
} }
internal override void Start() internal override void Start()
{ {
_steps = ESteps.LoadAppManifest; _steps = ESteps.QueryPackageVersion;
} }
internal override void Update() internal override void Update()
{ {
if (_steps == ESteps.None || _steps == ESteps.Done) if (_steps == ESteps.None || _steps == ESteps.Done)
return; return;
if (_steps == ESteps.QueryPackageVersion)
{
_appPackageVersionQuerier.Update();
if (_appPackageVersionQuerier.IsDone == false)
return;
string error = _appPackageVersionQuerier.Error;
if (string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = error;
}
else
{
_appManifestLoader = new AppManifestLoader(_packageName, _appPackageVersionQuerier.Version);
_steps = ESteps.LoadAppManifest;
}
}
if (_steps == ESteps.LoadAppManifest) if (_steps == ESteps.LoadAppManifest)
{ {
_appManifestLoader.Update(); _appManifestLoader.Update();
Progress = _appManifestLoader.Progress(); Progress = _appManifestLoader.Progress;
if (_appManifestLoader.IsDone() == false) if (_appManifestLoader.IsDone == false)
return; return;
if (_appManifestLoader.Result == null) if (_appManifestLoader.Manifest == null)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
@ -115,7 +139,7 @@ namespace YooAsset
else else
{ {
_steps = ESteps.InitVerifyingCache; _steps = ESteps.InitVerifyingCache;
_impl.SetAppPatchManifest(_appManifestLoader.Result); _impl.SetAppPatchManifest(_appManifestLoader.Manifest);
} }
} }
@ -146,71 +170,170 @@ namespace YooAsset
/// </summary> /// </summary>
internal sealed class HostPlayModeInitializationOperation : InitializationOperation internal sealed class HostPlayModeInitializationOperation : InitializationOperation
{ {
internal HostPlayModeInitializationOperation() private enum ESteps
{ {
None,
QueryPackageVersion,
LoadAppManifest,
CopyAppManifest,
InitVerifyingCache,
UpdateVerifyingCache,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly CacheVerifier _patchCacheVerifier;
private readonly AppPackageVersionQuerier _appPackageVersionQuerier;
private AppManifestCopyer _appManifestCopyer;
private AppManifestLoader _appManifestLoader;
private ESteps _steps = ESteps.None;
private float _verifyTime;
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl, string packageName)
{
_impl = impl;
_packageName = packageName;
_appPackageVersionQuerier = new AppPackageVersionQuerier(packageName);
#if UNITY_WEBGL
_patchCacheVerifier = new CacheVerifierWithoutThread();
#else
_patchCacheVerifier = new CacheVerifierWithThread();
#endif
} }
internal override void Start() internal override void Start()
{ {
Status = EOperationStatus.Succeed; _steps = ESteps.QueryPackageVersion;
} }
internal override void Update() internal override void Update()
{ {
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryPackageVersion)
{
_appPackageVersionQuerier.Update();
if (_appPackageVersionQuerier.IsDone == false)
return;
// 注意为了兼容MOD模式初始化动态新增的包裹的时候如果内置清单不存在也不需要报错
string error = _appPackageVersionQuerier.Error;
if (string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_appManifestCopyer = new AppManifestCopyer(_packageName, _appPackageVersionQuerier.Version);
_appManifestLoader = new AppManifestLoader(_packageName, _appPackageVersionQuerier.Version);
_steps = ESteps.CopyAppManifest;
}
}
if (_steps == ESteps.CopyAppManifest)
{
_appManifestCopyer.Update();
Progress = _appManifestCopyer.Progress;
if (_appManifestCopyer.IsDone == false)
return;
string error = _appManifestCopyer.Error;
if(string.IsNullOrEmpty(error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = error;
}
else
{
_steps = ESteps.LoadAppManifest;
}
}
if (_steps == ESteps.LoadAppManifest)
{
_appManifestLoader.Update();
Progress = _appManifestLoader.Progress;
if (_appManifestLoader.IsDone == false)
return;
if (_appManifestLoader.Manifest == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _appManifestLoader.Error;
}
else
{
_steps = ESteps.InitVerifyingCache;
_impl.SetLocalPatchManifest(_appManifestLoader.Manifest);
}
}
if (_steps == ESteps.InitVerifyingCache)
{
var verifyInfos = _impl.GetVerifyInfoList(false);
_patchCacheVerifier.InitVerifier(verifyInfos);
_verifyTime = UnityEngine.Time.realtimeSinceStartup;
_steps = ESteps.UpdateVerifyingCache;
}
if (_steps == ESteps.UpdateVerifyingCache)
{
Progress = _patchCacheVerifier.GetVerifierProgress();
if (_patchCacheVerifier.UpdateVerifier())
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyTime;
YooLogger.Log($"Verify result : Success {_patchCacheVerifier.VerifySuccessList.Count}, Fail {_patchCacheVerifier.VerifyFailList.Count}, Elapsed time {costTime} seconds");
}
}
} }
} }
/// <summary> // 内置补丁清单版本查询器
/// 内置补丁清单加载器 internal class AppPackageVersionQuerier
/// </summary>
internal class AppManifestLoader
{ {
private enum ESteps private enum ESteps
{ {
LoadStaticVersion, LoadStaticVersion,
CheckStaticVersion, CheckStaticVersion,
LoadAppManifest,
CheckAppManifest,
Done, Done,
} }
private readonly string _buildinPackageName; private readonly string _buildinPackageName;
private ESteps _steps = ESteps.LoadStaticVersion; private ESteps _steps = ESteps.LoadStaticVersion;
private UnityWebDataRequester _downloader1; private UnityWebDataRequester _downloader;
private UnityWebDataRequester _downloader2;
private string _buildinPackageVersion; /// <summary>
/// 内置包裹版本
/// </summary>
public string Version { private set; get; }
/// <summary> /// <summary>
/// 错误日志 /// 错误日志
/// </summary> /// </summary>
public string Error { private set; get; } public string Error { private set; get; }
/// <summary>
/// 加载结果
/// </summary>
public PatchManifest Result { private set; get; }
public AppManifestLoader(string buildinPackageName)
{
_buildinPackageName = buildinPackageName;
}
/// <summary> /// <summary>
/// 是否已经完成 /// 是否已经完成
/// </summary> /// </summary>
public bool IsDone() public bool IsDone
{
get
{ {
return _steps == ESteps.Done; return _steps == ESteps.Done;
} }
}
/// <summary>
/// 加载进度 public AppPackageVersionQuerier(string buildinPackageName)
/// </summary>
public float Progress()
{ {
if (_downloader2 == null) _buildinPackageName = buildinPackageName;
return 0;
return _downloader2.Progress();
} }
/// <summary> /// <summary>
@ -218,7 +341,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void Update() public void Update()
{ {
if (IsDone()) if (IsDone)
return; return;
if (_steps == ESteps.LoadStaticVersion) if (_steps == ESteps.LoadStaticVersion)
@ -226,73 +349,127 @@ namespace YooAsset
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(_buildinPackageName); string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(_buildinPackageName);
string filePath = PathHelper.MakeStreamingLoadPath(fileName); string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath); string url = PathHelper.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
_downloader1.SendRequest(url); _downloader.SendRequest(url);
_steps = ESteps.CheckStaticVersion; _steps = ESteps.CheckStaticVersion;
YooLogger.Log($"Load static version file : {filePath}");
} }
if (_steps == ESteps.CheckStaticVersion) if (_steps == ESteps.CheckStaticVersion)
{ {
if (_downloader1.IsDone() == false) if (_downloader.IsDone() == false)
return; return;
if (_downloader1.HasError()) if (_downloader.HasError())
{ {
Error = _downloader1.GetError(); Error = _downloader.GetError();
_steps = ESteps.Done;
} }
else else
{ {
_buildinPackageVersion = _downloader1.GetText(); Version = _downloader.GetText();
if (string.IsNullOrEmpty(_buildinPackageVersion)) if (string.IsNullOrEmpty(Version))
{
Error = $"Buildin package version is empty !"; Error = $"Buildin package version is empty !";
}
_steps = ESteps.Done; _steps = ESteps.Done;
_downloader.Dispose();
} }
else }
}
// 内置补丁清单加载器
internal class AppManifestLoader
{ {
_steps = ESteps.LoadAppManifest; private enum ESteps
{
LoadAppManifest,
CheckAppManifest,
Done,
}
private readonly string _buildinPackageName;
private readonly string _buildinPackageVersion;
private ESteps _steps = ESteps.LoadAppManifest;
private UnityWebDataRequester _downloader;
/// <summary>
/// 加载结果
/// </summary>
public PatchManifest Manifest { private set; get; }
/// <summary>
/// 错误日志
/// </summary>
public string Error { private set; get; }
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone
{
get
{
return _steps == ESteps.Done;
} }
} }
_downloader1.Dispose();
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (_downloader == null)
return 0;
return _downloader.Progress();
} }
}
public AppManifestLoader(string buildinPackageName, string buildinPackageVersion)
{
_buildinPackageName = buildinPackageName;
_buildinPackageVersion = buildinPackageVersion;
}
/// <summary>
/// 更新流程
/// </summary>
public void Update()
{
if (IsDone)
return;
if (_steps == ESteps.LoadAppManifest) if (_steps == ESteps.LoadAppManifest)
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageVersion);
string filePath = PathHelper.MakeStreamingLoadPath(fileName); string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath); string url = PathHelper.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
_downloader2.SendRequest(url); _downloader.SendRequest(url);
_steps = ESteps.CheckAppManifest; _steps = ESteps.CheckAppManifest;
YooLogger.Log($"Load patch manifest file : {filePath}");
} }
if (_steps == ESteps.CheckAppManifest) if (_steps == ESteps.CheckAppManifest)
{ {
if (_downloader2.IsDone() == false) if (_downloader.IsDone() == false)
return; return;
if (_downloader2.HasError()) if (_downloader.HasError())
{ {
Error = _downloader2.GetError(); Error = _downloader.GetError();
_steps = ESteps.Done;
} }
else else
{ {
// 解析APP里的补丁清单 // 解析APP里的补丁清单
Result = PatchManifest.Deserialize(_downloader2.GetText()); Manifest = PatchManifest.Deserialize(_downloader.GetText());
_steps = ESteps.Done;
} }
_downloader2.Dispose(); _steps = ESteps.Done;
_downloader.Dispose();
} }
} }
} }
/// <summary> // 内置补丁清单复制器
/// 内置补丁清单复制器
/// </summary>
internal class AppManifestCopyer internal class AppManifestCopyer
{ {
private enum ESteps private enum ESteps
@ -302,10 +479,10 @@ namespace YooAsset
Done, Done,
} }
private string _buildinPackageName; private readonly string _buildinPackageName;
private string _buildinPackageVersion; private readonly string _buildinPackageVersion;
private ESteps _steps = ESteps.CopyAppManifest; private ESteps _steps = ESteps.CopyAppManifest;
private UnityWebFileRequester _downloader1; private UnityWebFileRequester _downloader;
/// <summary> /// <summary>
/// 错误日志 /// 错误日志
@ -313,9 +490,28 @@ namespace YooAsset
public string Error { private set; get; } public string Error { private set; get; }
/// <summary> /// <summary>
/// 拷贝结果 /// 是否已经完成
/// </summary> /// </summary>
public bool Result { private set; get; } public bool IsDone
{
get
{
return _steps == ESteps.Done;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (_downloader == null)
return 0;
return _downloader.Progress();
}
}
public AppManifestCopyer(string buildinPackageName, string buildinPackageVersion) public AppManifestCopyer(string buildinPackageName, string buildinPackageVersion)
@ -329,7 +525,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void Update() public void Update()
{ {
if (IsDone()) if (IsDone)
return; return;
if (_steps == ESteps.CopyAppManifest) if (_steps == ESteps.CopyAppManifest)
@ -338,47 +534,30 @@ namespace YooAsset
string destFilePath = PathHelper.MakePersistentLoadPath(fileName); string destFilePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(destFilePath)) if (File.Exists(destFilePath))
{ {
Result = true;
_steps = ESteps.Done; _steps = ESteps.Done;
return;
} }
else else
{ {
YooLogger.Log($"Copy application patch manifest.");
string sourceFilePath = PathHelper.MakeStreamingLoadPath(fileName); string sourceFilePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(sourceFilePath); string url = PathHelper.ConvertToWWWPath(sourceFilePath);
_downloader1 = new UnityWebFileRequester(); _downloader = new UnityWebFileRequester();
_downloader1.SendRequest(url, destFilePath); _downloader.SendRequest(url, destFilePath);
_steps = ESteps.CheckAppManifest; _steps = ESteps.CheckAppManifest;
} }
} }
if (_steps == ESteps.CheckAppManifest) if (_steps == ESteps.CheckAppManifest)
{ {
if (_downloader1.IsDone() == false) if (_downloader.IsDone() == false)
return; return;
if (_downloader1.HasError()) if (_downloader.HasError())
{ {
Result = false; Error = _downloader.GetError();
Error = _downloader1.GetError(); }
_steps = ESteps.Done; _steps = ESteps.Done;
_downloader.Dispose();
} }
else
{
Result = true;
_steps = ESteps.Done;
}
_downloader1.Dispose();
}
}
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone()
{
return _steps == ESteps.Done;
} }
} }
} }

View File

@ -19,14 +19,14 @@ namespace YooAsset
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices) public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices, string packageName)
{ {
_locationToLower = locationToLower; _locationToLower = locationToLower;
_defaultHostServer = defaultHostServer; _defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer; _fallbackHostServer = fallbackHostServer;
_queryServices = queryServices; _queryServices = queryServices;
var operation = new HostPlayModeInitializationOperation(); var operation = new HostPlayModeInitializationOperation(this, packageName);
OperationSystem.StartOperation(operation); OperationSystem.StartOperation(operation);
return operation; return operation;
} }

View File

@ -13,10 +13,10 @@ namespace YooAsset
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, string buildinPackageName) public InitializationOperation InitializeAsync(bool locationToLower, string packageName)
{ {
_locationToLower = locationToLower; _locationToLower = locationToLower;
var operation = new OfflinePlayModeInitializationOperation(this, buildinPackageName); var operation = new OfflinePlayModeInitializationOperation(this, packageName);
OperationSystem.StartOperation(operation); OperationSystem.StartOperation(operation);
return operation; return operation;
} }