123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- using System.IO;
- namespace YooAsset
- {
- /// <summary>
- /// 原生文件操作
- /// </summary>
- public abstract class RawFileOperation : AsyncOperationBase
- {
- internal readonly BundleInfo _bundleInfo;
- /// <summary>
- /// 原生文件的拷贝路径
- /// </summary>
- public string CopyPath { private set; get; }
- internal RawFileOperation(BundleInfo bundleInfo, string copyPath)
- {
- _bundleInfo = bundleInfo;
- CopyPath = copyPath;
- }
- /// <summary>
- /// 原生文件的缓存路径
- /// </summary>
- public abstract string GetCachePath();
- /// <summary>
- /// 获取原生文件的二进制数据
- /// </summary>
- public byte[] LoadFileData()
- {
- string filePath = GetCachePath();
- if (File.Exists(filePath) == false)
- return null;
- return File.ReadAllBytes(filePath);
- }
- /// <summary>
- /// 获取原生文件的文本数据
- /// </summary>
- public string LoadFileText()
- {
- string filePath = GetCachePath();
- if (File.Exists(filePath) == false)
- return string.Empty;
- return File.ReadAllText(filePath, System.Text.Encoding.UTF8);
- }
- }
- /// <summary>
- /// 发生错误的原生文件操作
- /// </summary>
- internal sealed class CompletedRawFileOperation : RawFileOperation
- {
- private readonly string _error;
- internal CompletedRawFileOperation(string error, string copyPath) : base(null, copyPath)
- {
- _error = error;
- }
- internal override void Start()
- {
- Status = EOperationStatus.Failed;
- Error = _error;
- }
- internal override void Update()
- {
- }
- /// <summary>
- /// 原生文件的缓存路径
- /// </summary>
- public override string GetCachePath()
- {
- return string.Empty;
- }
- }
- /// <summary>
- /// 编辑器下模拟运行的原生文件操作
- /// </summary>
- internal sealed class EditorPlayModeRawFileOperation : RawFileOperation
- {
- private enum ESteps
- {
- None,
- Prepare,
- CheckAndCopyFile,
- Done,
- }
- private ESteps _steps = ESteps.None;
- internal EditorPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
- {
- }
- internal override void Start()
- {
- _steps = ESteps.Prepare;
- }
- internal override void Update()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
- // 1. 准备工作
- if (_steps == ESteps.Prepare)
- {
- if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor)
- {
- _steps = ESteps.CheckAndCopyFile;
- return; // 模拟实现异步操作
- }
- else
- {
- throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
- }
- }
- // 2. 检测并拷贝原生文件
- if (_steps == ESteps.CheckAndCopyFile)
- {
- // 如果不需要保存文件
- if (string.IsNullOrEmpty(CopyPath))
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- return;
- }
- // 如果原生文件已经存在,则将其删除
- if (File.Exists(CopyPath))
- {
- File.Delete(CopyPath);
- }
- try
- {
- FileUtility.CreateFileDirectory(CopyPath);
- File.Copy(GetCachePath(), CopyPath, true);
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- catch (System.Exception e)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = e.ToString();
- }
- }
- }
- /// <summary>
- /// 原生文件的缓存路径
- /// </summary>
- public override string GetCachePath()
- {
- if (_bundleInfo == null)
- return string.Empty;
- return _bundleInfo.EditorAssetPath;
- }
- }
- /// <summary>
- /// 离线模式的原生文件操作
- /// </summary>
- internal sealed class OfflinePlayModeRawFileOperation : RawFileOperation
- {
- private enum ESteps
- {
- None,
- Prepare,
- DownloadBuildinFile,
- CheckDownload,
- CheckAndCopyFile,
- Done,
- }
- private ESteps _steps = ESteps.None;
- private DownloaderBase _downloader;
- public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
- {
- }
- internal override void Start()
- {
- _steps = ESteps.Prepare;
- }
- internal override void Update()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
- // 1. 准备工作
- if (_steps == ESteps.Prepare)
- {
- if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
- }
- else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
- _steps = ESteps.DownloadBuildinFile;
- }
- else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
- {
- _steps = ESteps.CheckAndCopyFile;
- }
- else
- {
- throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
- }
- }
- // 2. 下载文件
- if (_steps == ESteps.DownloadBuildinFile)
- {
- int failedTryAgain = int.MaxValue;
- var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
- _downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
- _steps = ESteps.CheckDownload;
- }
- // 3. 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- Progress = _downloader.DownloadProgress;
- if (_downloader.IsDone() == false)
- return;
- if (_downloader.HasError())
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = _downloader.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckAndCopyFile;
- }
- }
- // 4. 检测并拷贝原生文件
- if (_steps == ESteps.CheckAndCopyFile)
- {
- // 如果不需要保存文件
- if (string.IsNullOrEmpty(CopyPath))
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- return;
- }
- // 如果原生文件已经存在,则验证其完整性
- if (File.Exists(CopyPath))
- {
- var verifyResult = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
- if (verifyResult == EVerifyResult.Succeed)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- return;
- }
- else
- {
- File.Delete(CopyPath);
- }
- }
- try
- {
- FileUtility.CreateFileDirectory(CopyPath);
- File.Copy(GetCachePath(), CopyPath, true);
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- catch (System.Exception e)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = e.ToString();
- }
- }
- }
- /// <summary>
- /// 原生文件的缓存路径
- /// </summary>
- public override string GetCachePath()
- {
- if (_bundleInfo == null)
- return string.Empty;
- return _bundleInfo.Bundle.CachedFilePath;
- }
- }
- /// <summary>
- /// 联机模式的原生文件操作
- /// </summary>
- internal sealed class HostPlayModeRawFileOperation : RawFileOperation
- {
- private enum ESteps
- {
- None,
- Prepare,
- DownloadWebFile,
- DownloadBuildinFile,
- CheckDownload,
- CheckAndCopyFile,
- Done,
- }
- private ESteps _steps = ESteps.None;
- private DownloaderBase _downloader;
- internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
- {
- }
- internal override void Start()
- {
- _steps = ESteps.Prepare;
- }
- internal override void Update()
- {
- if (_steps == ESteps.None || _steps == ESteps.Done)
- return;
- // 1. 准备工作
- if (_steps == ESteps.Prepare)
- {
- if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
- }
- else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
- {
- _steps = ESteps.DownloadWebFile;
- }
- else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
- {
- _steps = ESteps.DownloadBuildinFile;
- }
- else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
- {
- _steps = ESteps.CheckAndCopyFile;
- }
- else
- {
- throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
- }
- }
- // 2. 下载远端文件
- if (_steps == ESteps.DownloadWebFile)
- {
- int failedTryAgain = int.MaxValue;
- _downloader = DownloadSystem.BeginDownload(_bundleInfo, failedTryAgain);
- _steps = ESteps.CheckDownload;
- }
- // 3. 下载内置文件
- if (_steps == ESteps.DownloadBuildinFile)
- {
- int failedTryAgain = int.MaxValue;
- var bundleInfo = PatchHelper.ConvertToUnpackInfo(_bundleInfo.Bundle);
- _downloader = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
- _steps = ESteps.CheckDownload;
- }
- // 4. 检测下载结果
- if (_steps == ESteps.CheckDownload)
- {
- Progress = _downloader.DownloadProgress;
- if (_downloader.IsDone() == false)
- return;
- if (_downloader.HasError())
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = _downloader.GetLastError();
- }
- else
- {
- _steps = ESteps.CheckAndCopyFile;
- }
- }
- // 5. 检测并拷贝原生文件
- if (_steps == ESteps.CheckAndCopyFile)
- {
- // 如果不需要保存文件
- if (string.IsNullOrEmpty(CopyPath))
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- return;
- }
- // 如果原生文件已经存在,则验证其完整性
- if (File.Exists(CopyPath))
- {
- var verifyResult = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
- if (verifyResult == EVerifyResult.Succeed)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- return;
- }
- else
- {
- File.Delete(CopyPath);
- }
- }
- try
- {
- FileUtility.CreateFileDirectory(CopyPath);
- File.Copy(GetCachePath(), CopyPath, true);
- _steps = ESteps.Done;
- Status = EOperationStatus.Succeed;
- }
- catch (System.Exception e)
- {
- _steps = ESteps.Done;
- Status = EOperationStatus.Failed;
- Error = e.ToString();
- }
- }
- }
- /// <summary>
- /// 原生文件的缓存路径
- /// </summary>
- public override string GetCachePath()
- {
- if (_bundleInfo == null)
- return string.Empty;
- return _bundleInfo.Bundle.CachedFilePath;
- }
- }
- }
|