505 lines
18 KiB
C#
505 lines
18 KiB
C#
![]() |
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace YooAsset
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 初始化操作
|
|||
|
/// </summary>
|
|||
|
public abstract class InitializationOperation : AsyncOperationBase
|
|||
|
{
|
|||
|
public string PackageVersion { protected set; get; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 编辑器下模拟模式的初始化操作
|
|||
|
/// </summary>
|
|||
|
internal sealed class EditorSimulateModeInitializationOperation : InitializationOperation
|
|||
|
{
|
|||
|
private enum ESteps
|
|||
|
{
|
|||
|
None,
|
|||
|
LoadEditorManifest,
|
|||
|
Done,
|
|||
|
}
|
|||
|
|
|||
|
private readonly EditorSimulateModeImpl _impl;
|
|||
|
private readonly string _simulateManifestFilePath;
|
|||
|
private LoadEditorManifestOperation _loadEditorManifestOp;
|
|||
|
private ESteps _steps = ESteps.None;
|
|||
|
|
|||
|
internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestFilePath)
|
|||
|
{
|
|||
|
_impl = impl;
|
|||
|
_simulateManifestFilePath = simulateManifestFilePath;
|
|||
|
}
|
|||
|
internal override void InternalOnStart()
|
|||
|
{
|
|||
|
_steps = ESteps.LoadEditorManifest;
|
|||
|
}
|
|||
|
internal override void InternalOnUpdate()
|
|||
|
{
|
|||
|
if (_steps == ESteps.LoadEditorManifest)
|
|||
|
{
|
|||
|
if (_loadEditorManifestOp == null)
|
|||
|
{
|
|||
|
_loadEditorManifestOp = new LoadEditorManifestOperation(_impl.PackageName, _simulateManifestFilePath);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _loadEditorManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_loadEditorManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_loadEditorManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
PackageVersion = _loadEditorManifestOp.Manifest.PackageVersion;
|
|||
|
_impl.ActiveManifest = _loadEditorManifestOp.Manifest;
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Succeed;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _loadEditorManifestOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 离线运行模式的初始化操作
|
|||
|
/// </summary>
|
|||
|
internal sealed class OfflinePlayModeInitializationOperation : InitializationOperation
|
|||
|
{
|
|||
|
private enum ESteps
|
|||
|
{
|
|||
|
None,
|
|||
|
QueryBuildinPackageVersion,
|
|||
|
LoadBuildinManifest,
|
|||
|
PackageCaching,
|
|||
|
Done,
|
|||
|
}
|
|||
|
|
|||
|
private readonly OfflinePlayModeImpl _impl;
|
|||
|
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
|
|||
|
private LoadBuildinManifestOperation _loadBuildinManifestOp;
|
|||
|
private PackageCachingOperation _cachingOperation;
|
|||
|
private ESteps _steps = ESteps.None;
|
|||
|
|
|||
|
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl)
|
|||
|
{
|
|||
|
_impl = impl;
|
|||
|
}
|
|||
|
internal override void InternalOnStart()
|
|||
|
{
|
|||
|
_steps = ESteps.QueryBuildinPackageVersion;
|
|||
|
}
|
|||
|
internal override void InternalOnUpdate()
|
|||
|
{
|
|||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
|||
|
return;
|
|||
|
|
|||
|
if (_steps == ESteps.QueryBuildinPackageVersion)
|
|||
|
{
|
|||
|
if (_queryBuildinPackageVersionOp == null)
|
|||
|
{
|
|||
|
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_queryBuildinPackageVersionOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.LoadBuildinManifest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _queryBuildinPackageVersionOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.LoadBuildinManifest)
|
|||
|
{
|
|||
|
if (_loadBuildinManifestOp == null)
|
|||
|
{
|
|||
|
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
Progress = _loadBuildinManifestOp.Progress;
|
|||
|
if (_loadBuildinManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
|
|||
|
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
|
|||
|
_steps = ESteps.PackageCaching;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _loadBuildinManifestOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.PackageCaching)
|
|||
|
{
|
|||
|
if (_cachingOperation == null)
|
|||
|
{
|
|||
|
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _cachingOperation);
|
|||
|
}
|
|||
|
|
|||
|
Progress = _cachingOperation.Progress;
|
|||
|
if (_cachingOperation.IsDone)
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Succeed;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 联机运行模式的初始化操作
|
|||
|
/// 注意:优先从沙盒里加载清单,如果沙盒里不存在就尝试把内置清单拷贝到沙盒并加载该清单。
|
|||
|
/// </summary>
|
|||
|
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
|
|||
|
{
|
|||
|
private enum ESteps
|
|||
|
{
|
|||
|
None,
|
|||
|
CheckAppFootPrint,
|
|||
|
QueryCachePackageVersion,
|
|||
|
TryLoadCacheManifest,
|
|||
|
QueryBuildinPackageVersion,
|
|||
|
UnpackBuildinManifest,
|
|||
|
LoadBuildinManifest,
|
|||
|
PackageCaching,
|
|||
|
Done,
|
|||
|
}
|
|||
|
|
|||
|
private readonly HostPlayModeImpl _impl;
|
|||
|
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
|
|||
|
private QueryCachePackageVersionOperation _queryCachePackageVersionOp;
|
|||
|
private UnpackBuildinManifestOperation _unpackBuildinManifestOp;
|
|||
|
private LoadBuildinManifestOperation _loadBuildinManifestOp;
|
|||
|
private LoadCacheManifestOperation _loadCacheManifestOp;
|
|||
|
private PackageCachingOperation _cachingOperation;
|
|||
|
private ESteps _steps = ESteps.None;
|
|||
|
|
|||
|
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl)
|
|||
|
{
|
|||
|
_impl = impl;
|
|||
|
}
|
|||
|
internal override void InternalOnStart()
|
|||
|
{
|
|||
|
_steps = ESteps.CheckAppFootPrint;
|
|||
|
}
|
|||
|
internal override void InternalOnUpdate()
|
|||
|
{
|
|||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
|||
|
return;
|
|||
|
|
|||
|
if (_steps == ESteps.CheckAppFootPrint)
|
|||
|
{
|
|||
|
var appFootPrint = new AppFootPrint(_impl.Persistent);
|
|||
|
appFootPrint.Load(_impl.PackageName);
|
|||
|
|
|||
|
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
|
|||
|
if (appFootPrint.IsDirty())
|
|||
|
{
|
|||
|
_impl.Persistent.DeleteSandboxManifestFilesFolder();
|
|||
|
appFootPrint.Coverage(_impl.PackageName);
|
|||
|
YooLogger.Log("Delete manifest files when application foot print dirty !");
|
|||
|
}
|
|||
|
_steps = ESteps.QueryCachePackageVersion;
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.QueryCachePackageVersion)
|
|||
|
{
|
|||
|
if (_queryCachePackageVersionOp == null)
|
|||
|
{
|
|||
|
_queryCachePackageVersionOp = new QueryCachePackageVersionOperation(_impl.Persistent);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _queryCachePackageVersionOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_queryCachePackageVersionOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_queryCachePackageVersionOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.TryLoadCacheManifest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.QueryBuildinPackageVersion;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.TryLoadCacheManifest)
|
|||
|
{
|
|||
|
if (_loadCacheManifestOp == null)
|
|||
|
{
|
|||
|
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _queryCachePackageVersionOp.PackageVersion);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_loadCacheManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion;
|
|||
|
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
|
|||
|
_steps = ESteps.PackageCaching;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.QueryBuildinPackageVersion;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.QueryBuildinPackageVersion)
|
|||
|
{
|
|||
|
if (_queryBuildinPackageVersionOp == null)
|
|||
|
{
|
|||
|
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_queryBuildinPackageVersionOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.UnpackBuildinManifest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 注意:为了兼容MOD模式,初始化动态新增的包裹的时候,如果内置清单不存在也不需要报错!
|
|||
|
_steps = ESteps.PackageCaching;
|
|||
|
string error = _queryBuildinPackageVersionOp.Error;
|
|||
|
YooLogger.Log($"Failed to load buildin package version file : {error}");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.UnpackBuildinManifest)
|
|||
|
{
|
|||
|
if (_unpackBuildinManifestOp == null)
|
|||
|
{
|
|||
|
_unpackBuildinManifestOp = new UnpackBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _unpackBuildinManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_unpackBuildinManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_unpackBuildinManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.LoadBuildinManifest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _unpackBuildinManifestOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.LoadBuildinManifest)
|
|||
|
{
|
|||
|
if (_loadBuildinManifestOp == null)
|
|||
|
{
|
|||
|
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
Progress = _loadBuildinManifestOp.Progress;
|
|||
|
if (_loadBuildinManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
|
|||
|
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
|
|||
|
_impl.FlushManifestVersionFile(); //注意:解压内置清单并加载成功后保存该清单版本。
|
|||
|
_steps = ESteps.PackageCaching;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _loadBuildinManifestOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.PackageCaching)
|
|||
|
{
|
|||
|
if (_cachingOperation == null)
|
|||
|
{
|
|||
|
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _cachingOperation);
|
|||
|
}
|
|||
|
|
|||
|
Progress = _cachingOperation.Progress;
|
|||
|
if (_cachingOperation.IsDone)
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Succeed;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// WebGL运行模式的初始化操作
|
|||
|
/// </summary>
|
|||
|
internal sealed class WebPlayModeInitializationOperation : InitializationOperation
|
|||
|
{
|
|||
|
private enum ESteps
|
|||
|
{
|
|||
|
None,
|
|||
|
QueryWebPackageVersion,
|
|||
|
LoadWebManifest,
|
|||
|
Done,
|
|||
|
}
|
|||
|
|
|||
|
private readonly WebPlayModeImpl _impl;
|
|||
|
private QueryBuildinPackageVersionOperation _queryWebPackageVersionOp;
|
|||
|
private LoadBuildinManifestOperation _loadWebManifestOp;
|
|||
|
private ESteps _steps = ESteps.None;
|
|||
|
|
|||
|
internal WebPlayModeInitializationOperation(WebPlayModeImpl impl)
|
|||
|
{
|
|||
|
_impl = impl;
|
|||
|
}
|
|||
|
internal override void InternalOnStart()
|
|||
|
{
|
|||
|
_steps = ESteps.QueryWebPackageVersion;
|
|||
|
}
|
|||
|
internal override void InternalOnUpdate()
|
|||
|
{
|
|||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
|||
|
return;
|
|||
|
|
|||
|
if (_steps == ESteps.QueryWebPackageVersion)
|
|||
|
{
|
|||
|
if (_queryWebPackageVersionOp == null)
|
|||
|
{
|
|||
|
_queryWebPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _queryWebPackageVersionOp);
|
|||
|
}
|
|||
|
|
|||
|
if (_queryWebPackageVersionOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_queryWebPackageVersionOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
_steps = ESteps.LoadWebManifest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 注意:WebGL平台可能因为网络的原因会导致请求失败。如果内置清单不存在或者超时也不需要报错!
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Succeed;
|
|||
|
string error = _queryWebPackageVersionOp.Error;
|
|||
|
YooLogger.Log($"Failed to load web package version file : {error}");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_steps == ESteps.LoadWebManifest)
|
|||
|
{
|
|||
|
if (_loadWebManifestOp == null)
|
|||
|
{
|
|||
|
_loadWebManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryWebPackageVersionOp.PackageVersion);
|
|||
|
OperationSystem.StartOperation(_impl.PackageName, _loadWebManifestOp);
|
|||
|
}
|
|||
|
|
|||
|
Progress = _loadWebManifestOp.Progress;
|
|||
|
if (_loadWebManifestOp.IsDone == false)
|
|||
|
return;
|
|||
|
|
|||
|
if (_loadWebManifestOp.Status == EOperationStatus.Succeed)
|
|||
|
{
|
|||
|
PackageVersion = _loadWebManifestOp.Manifest.PackageVersion;
|
|||
|
_impl.ActiveManifest = _loadWebManifestOp.Manifest;
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Succeed;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_steps = ESteps.Done;
|
|||
|
Status = EOperationStatus.Failed;
|
|||
|
Error = _loadWebManifestOp.Error;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 应用程序水印
|
|||
|
/// </summary>
|
|||
|
internal class AppFootPrint
|
|||
|
{
|
|||
|
private PersistentManager _persistent;
|
|||
|
private string _footPrint;
|
|||
|
|
|||
|
public AppFootPrint(PersistentManager persistent)
|
|||
|
{
|
|||
|
_persistent = persistent;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 读取应用程序水印
|
|||
|
/// </summary>
|
|||
|
public void Load(string packageName)
|
|||
|
{
|
|||
|
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
|
|||
|
if (File.Exists(footPrintFilePath))
|
|||
|
{
|
|||
|
_footPrint = FileUtility.ReadAllText(footPrintFilePath);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Coverage(packageName);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 检测水印是否发生变化
|
|||
|
/// </summary>
|
|||
|
public bool IsDirty()
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
return _footPrint != Application.version;
|
|||
|
#else
|
|||
|
return _footPrint != Application.buildGUID;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 覆盖掉水印
|
|||
|
/// </summary>
|
|||
|
public void Coverage(string packageName)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
_footPrint = Application.version;
|
|||
|
#else
|
|||
|
_footPrint = Application.buildGUID;
|
|||
|
#endif
|
|||
|
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
|
|||
|
FileUtility.WriteAllText(footPrintFilePath, _footPrint);
|
|||
|
YooLogger.Log($"Save application foot print : {_footPrint}");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|