LoadCacheManifestOperation.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System.IO;
  2. namespace YooAsset
  3. {
  4. internal class LoadCacheManifestOperation : AsyncOperationBase
  5. {
  6. private enum ESteps
  7. {
  8. None,
  9. QueryCachePackageHash,
  10. VerifyFileHash,
  11. LoadCacheManifest,
  12. CheckDeserializeManifest,
  13. Done,
  14. }
  15. private readonly string _packageName;
  16. private readonly string _packageVersion;
  17. private QueryCachePackageHashOperation _queryCachePackageHashOp;
  18. private DeserializeManifestOperation _deserializer;
  19. private string _manifestFilePath;
  20. private ESteps _steps = ESteps.None;
  21. /// <summary>
  22. /// 加载的清单实例
  23. /// </summary>
  24. public PackageManifest Manifest { private set; get; }
  25. public LoadCacheManifestOperation(string packageName, string packageVersion)
  26. {
  27. _packageName = packageName;
  28. _packageVersion = packageVersion;
  29. }
  30. internal override void Start()
  31. {
  32. _steps = ESteps.QueryCachePackageHash;
  33. }
  34. internal override void Update()
  35. {
  36. if (_steps == ESteps.None || _steps == ESteps.Done)
  37. return;
  38. if (_steps == ESteps.QueryCachePackageHash)
  39. {
  40. if (_queryCachePackageHashOp == null)
  41. {
  42. _queryCachePackageHashOp = new QueryCachePackageHashOperation(_packageName, _packageVersion);
  43. OperationSystem.StartOperation(_queryCachePackageHashOp);
  44. }
  45. if (_queryCachePackageHashOp.IsDone == false)
  46. return;
  47. if (_queryCachePackageHashOp.Status == EOperationStatus.Succeed)
  48. {
  49. _steps = ESteps.VerifyFileHash;
  50. }
  51. else
  52. {
  53. _steps = ESteps.Done;
  54. Status = EOperationStatus.Failed;
  55. Error = _queryCachePackageHashOp.Error;
  56. ClearCacheFile();
  57. }
  58. }
  59. if (_steps == ESteps.VerifyFileHash)
  60. {
  61. _manifestFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageManifestFilePath(_packageVersion);
  62. if (File.Exists(_manifestFilePath) == false)
  63. {
  64. _steps = ESteps.Done;
  65. Status = EOperationStatus.Failed;
  66. Error = $"Not found cache manifest file : {_manifestFilePath}";
  67. ClearCacheFile();
  68. return;
  69. }
  70. string fileHash = HashUtility.FileMD5(_manifestFilePath);
  71. if (fileHash != _queryCachePackageHashOp.PackageHash)
  72. {
  73. _steps = ESteps.Done;
  74. Status = EOperationStatus.Failed;
  75. Error = "Failed to verify cache manifest file hash !";
  76. ClearCacheFile();
  77. }
  78. else
  79. {
  80. _steps = ESteps.LoadCacheManifest;
  81. }
  82. }
  83. if (_steps == ESteps.LoadCacheManifest)
  84. {
  85. byte[] bytesData = File.ReadAllBytes(_manifestFilePath);
  86. _deserializer = new DeserializeManifestOperation(bytesData);
  87. OperationSystem.StartOperation(_deserializer);
  88. _steps = ESteps.CheckDeserializeManifest;
  89. }
  90. if (_steps == ESteps.CheckDeserializeManifest)
  91. {
  92. Progress = _deserializer.Progress;
  93. if (_deserializer.IsDone == false)
  94. return;
  95. if (_deserializer.Status == EOperationStatus.Succeed)
  96. {
  97. Manifest = _deserializer.Manifest;
  98. _steps = ESteps.Done;
  99. Status = EOperationStatus.Succeed;
  100. }
  101. else
  102. {
  103. _steps = ESteps.Done;
  104. Status = EOperationStatus.Failed;
  105. Error = _deserializer.Error;
  106. ClearCacheFile();
  107. }
  108. }
  109. }
  110. private void ClearCacheFile()
  111. {
  112. // 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。
  113. if (File.Exists(_manifestFilePath))
  114. {
  115. YooLogger.Warning($"Failed to load cache manifest file : {Error}");
  116. YooLogger.Warning($"Invalid cache manifest file have been removed : {_manifestFilePath}");
  117. File.Delete(_manifestFilePath);
  118. }
  119. string hashFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageHashFilePath(_packageVersion);
  120. if (File.Exists(hashFilePath))
  121. {
  122. File.Delete(hashFilePath);
  123. }
  124. }
  125. }
  126. }