PatchCacheVerifier.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Threading;
  6. namespace YooAsset
  7. {
  8. /// <summary>
  9. /// 本地缓存文件验证器
  10. /// </summary>
  11. internal abstract class PatchCacheVerifier
  12. {
  13. public abstract bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate);
  14. public abstract bool UpdateVerifier();
  15. public abstract float GetVerifierProgress();
  16. public int VerifySuccessCount { protected set; get; } = 0;
  17. public int VerifyFailCount { protected set; get; } = 0;
  18. }
  19. /// <summary>
  20. /// 本地缓存文件验证器(线程版)
  21. /// </summary>
  22. internal class PatchCacheVerifierWithThread : PatchCacheVerifier
  23. {
  24. private class ThreadInfo
  25. {
  26. public EVerifyResult Result;
  27. public string FilePath { private set; get; }
  28. public PatchBundle Bundle { private set; get; }
  29. public ThreadInfo(string filePath, PatchBundle bundle)
  30. {
  31. FilePath = filePath;
  32. Bundle = bundle;
  33. }
  34. }
  35. private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
  36. private readonly List<PatchBundle> _waitingList = new List<PatchBundle>(1000);
  37. private readonly List<PatchBundle> _verifyingList = new List<PatchBundle>(100);
  38. private int _verifyMaxNum;
  39. private int _verifyTotalCount;
  40. public override bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate)
  41. {
  42. // 遍历所有文件然后验证并缓存合法文件
  43. foreach (var patchBundle in localPatchManifest.BundleList)
  44. {
  45. // 忽略缓存文件
  46. if (CacheSystem.IsCached(patchBundle))
  47. continue;
  48. // 忽略APP资源
  49. // 注意:如果是APP资源并且哈希值相同,则不需要下载
  50. if (appPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
  51. {
  52. if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
  53. continue;
  54. }
  55. // 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
  56. if (weaklyUpdate)
  57. {
  58. string filePath = patchBundle.CachedFilePath;
  59. if (File.Exists(filePath))
  60. _waitingList.Add(patchBundle);
  61. else
  62. return false;
  63. }
  64. else
  65. {
  66. string filePath = patchBundle.CachedFilePath;
  67. if (File.Exists(filePath))
  68. _waitingList.Add(patchBundle);
  69. }
  70. }
  71. // 设置同时验证的最大数
  72. ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
  73. YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
  74. _verifyMaxNum = Math.Min(workerThreads, ioThreads);
  75. _verifyTotalCount = _waitingList.Count;
  76. if (_verifyMaxNum < 1)
  77. _verifyMaxNum = 1;
  78. return true;
  79. }
  80. public override bool UpdateVerifier()
  81. {
  82. _syncContext.Update();
  83. if (_waitingList.Count == 0 && _verifyingList.Count == 0)
  84. return true;
  85. if (_verifyingList.Count >= _verifyMaxNum)
  86. return false;
  87. for (int i = _waitingList.Count - 1; i >= 0; i--)
  88. {
  89. if (_verifyingList.Count >= _verifyMaxNum)
  90. break;
  91. var patchBundle = _waitingList[i];
  92. if (VerifyFile(patchBundle))
  93. {
  94. _waitingList.RemoveAt(i);
  95. _verifyingList.Add(patchBundle);
  96. }
  97. else
  98. {
  99. YooLogger.Warning("The thread pool is failed queued.");
  100. break;
  101. }
  102. }
  103. return false;
  104. }
  105. public override float GetVerifierProgress()
  106. {
  107. if (_verifyTotalCount == 0)
  108. return 1f;
  109. return (float)(VerifySuccessCount + VerifyFailCount) / _verifyTotalCount;
  110. }
  111. private bool VerifyFile(PatchBundle patchBundle)
  112. {
  113. string filePath = patchBundle.CachedFilePath;
  114. ThreadInfo info = new ThreadInfo(filePath, patchBundle);
  115. return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), info);
  116. }
  117. private void VerifyInThread(object infoObj)
  118. {
  119. ThreadInfo info = (ThreadInfo)infoObj;
  120. info.Result = CacheSystem.VerifyBundle(info.Bundle, CacheSystem.InitVerifyLevel);
  121. _syncContext.Post(VerifyCallback, info);
  122. }
  123. private void VerifyCallback(object obj)
  124. {
  125. ThreadInfo info = (ThreadInfo)obj;
  126. if (info.Result == EVerifyResult.Succeed)
  127. {
  128. VerifySuccessCount++;
  129. CacheSystem.CacheBundle(info.Bundle);
  130. }
  131. else
  132. {
  133. VerifyFailCount++;
  134. YooLogger.Warning($"Failed to verify file : {info.Bundle.CachedFilePath}");
  135. // NOTE:不期望删除断点续传的资源文件
  136. /*
  137. if (File.Exists(patchBundle.CachedBundleFilePath))
  138. File.Delete(patchBundle.CachedBundleFilePath);
  139. */
  140. }
  141. _verifyingList.Remove(info.Bundle);
  142. }
  143. }
  144. /// <summary>
  145. /// 本地缓存文件验证器(非线程版)
  146. /// </summary>
  147. internal class PatchCacheVerifierWithoutThread : PatchCacheVerifier
  148. {
  149. private readonly List<PatchBundle> _waitingList = new List<PatchBundle>(1000);
  150. private readonly List<PatchBundle> _verifyingList = new List<PatchBundle>(100);
  151. private int _verifyMaxNum;
  152. private int _verifyTotalCount;
  153. public override bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate)
  154. {
  155. // 遍历所有文件然后验证并缓存合法文件
  156. foreach (var patchBundle in localPatchManifest.BundleList)
  157. {
  158. // 忽略缓存文件
  159. if (CacheSystem.IsCached(patchBundle))
  160. continue;
  161. // 忽略APP资源
  162. // 注意:如果是APP资源并且哈希值相同,则不需要下载
  163. if (appPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
  164. {
  165. if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
  166. continue;
  167. }
  168. // 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
  169. if (weaklyUpdate)
  170. {
  171. string filePath = patchBundle.CachedFilePath;
  172. if (File.Exists(filePath))
  173. _waitingList.Add(patchBundle);
  174. else
  175. return false;
  176. }
  177. else
  178. {
  179. string filePath = patchBundle.CachedFilePath;
  180. if (File.Exists(filePath))
  181. _waitingList.Add(patchBundle);
  182. }
  183. }
  184. // 设置同时验证的最大数
  185. _verifyMaxNum = 32;
  186. _verifyTotalCount = _waitingList.Count;
  187. return true;
  188. }
  189. public override bool UpdateVerifier()
  190. {
  191. if (_waitingList.Count == 0 && _verifyingList.Count == 0)
  192. return true;
  193. for (int i = _waitingList.Count - 1; i >= 0; i--)
  194. {
  195. if (_verifyingList.Count >= _verifyMaxNum)
  196. break;
  197. var patchBundle = _waitingList[i];
  198. VerifyFile(patchBundle);
  199. _waitingList.RemoveAt(i);
  200. _verifyingList.Add(patchBundle);
  201. }
  202. _verifyingList.Clear();
  203. return false;
  204. }
  205. public override float GetVerifierProgress()
  206. {
  207. if (_verifyTotalCount == 0)
  208. return 1f;
  209. return (float)(VerifySuccessCount + VerifyFailCount) / _verifyTotalCount;
  210. }
  211. private void VerifyFile(PatchBundle patchBundle)
  212. {
  213. var verifyResult = CacheSystem.VerifyAndCacheBundle(patchBundle, CacheSystem.InitVerifyLevel);
  214. if (verifyResult == EVerifyResult.Succeed)
  215. {
  216. VerifySuccessCount++;
  217. }
  218. else
  219. {
  220. VerifyFailCount++;
  221. YooLogger.Warning($"Failed to verify file : {patchBundle.CachedFilePath}");
  222. // NOTE:不期望删除断点续传的资源文件
  223. /*
  224. if (File.Exists(patchBundle.CachedBundleFilePath))
  225. File.Delete(patchBundle.CachedBundleFilePath);
  226. */
  227. }
  228. }
  229. }
  230. }