VersionController.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using GFGGame.Launcher;
  2. using System.Collections;
  3. using UnityEngine;
  4. using YooAsset;
  5. namespace GFGGame
  6. {
  7. public class VersionController : SingletonMonoBase<VersionController>
  8. {
  9. public const string DefaultPackage = "GameLogic";
  10. /// <summary>
  11. /// 包裹的版本信息
  12. /// </summary>
  13. public string PackageVersion { set; get; }
  14. public void Init()
  15. {
  16. // 初始化资源系统
  17. YooAssets.Initialize();
  18. StartCoroutine(InitVersion());
  19. }
  20. public IEnumerator InitVersion()
  21. {
  22. yield return InitDefaultPackage();
  23. yield return GetStaticVersion(DefaultPackage);
  24. yield return UpdateManifest(DefaultPackage);
  25. CreateDownloader(DefaultPackage);
  26. }
  27. private IEnumerator InitDefaultPackage()
  28. {
  29. // 创建默认的资源包
  30. string packageName = DefaultPackage;
  31. var package = YooAssets.TryGetPackage(packageName);
  32. if (package == null)
  33. {
  34. package = YooAssets.CreatePackage(packageName);
  35. YooAssets.SetDefaultPackage(package);
  36. }
  37. var playMode = GameLauncher.Instance.PlayMode;
  38. #if !UNITY_EDITOR
  39. playMode = EPlayMode.HostPlayMode;
  40. #endif
  41. InitializationOperation initializationOperation = null;
  42. if (playMode == EPlayMode.EditorSimulateMode)
  43. {
  44. // 编辑器下的模拟模式
  45. var createParameters = new EditorSimulateModeParameters();
  46. createParameters.SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(packageName);
  47. initializationOperation = package.InitializeAsync(createParameters);
  48. }
  49. else if (playMode == EPlayMode.HostPlayMode)
  50. {
  51. // 联机运行模式
  52. string defaultHostServer = GetHostServerURL(DefaultPackage);
  53. string fallbackHostServer = defaultHostServer;
  54. var createParameters = new HostPlayModeParameters();
  55. //createParameters.DecryptionServices = new GameDecryptionServices();
  56. createParameters.QueryServices = new GameQueryServices();
  57. createParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
  58. initializationOperation = package.InitializeAsync(createParameters);
  59. }
  60. yield return initializationOperation;
  61. if (initializationOperation.Status != EOperationStatus.Succeed)
  62. {
  63. Debug.LogWarning($"{initializationOperation.Error}");
  64. }
  65. }
  66. private IEnumerator GetStaticVersion(string packageName)
  67. {
  68. var package = YooAssets.GetPackage(packageName);
  69. var operation = package.UpdatePackageVersionAsync();
  70. yield return operation;
  71. if (operation.Status == EOperationStatus.Succeed)
  72. {
  73. VersionController.Instance.PackageVersion = operation.PackageVersion;
  74. Debug.Log($"远端最新版本为: {operation.PackageVersion}");
  75. }
  76. else
  77. {
  78. Debug.LogWarning(operation.Error);
  79. }
  80. }
  81. private IEnumerator UpdateManifest(string packageName)
  82. {
  83. bool savePackageVersion = true;
  84. var package = YooAssets.GetPackage(packageName);
  85. var operation = package.UpdatePackageManifestAsync(VersionController.Instance.PackageVersion, savePackageVersion);
  86. yield return operation;
  87. if (operation.Status != EOperationStatus.Succeed)
  88. {
  89. Debug.LogWarning(operation.Error);
  90. Alert.Show("更新版本信息失败,请检测网络链接后重试。")
  91. .SetLeftButton(true, "重试", (data) => { StartCoroutine(UpdateManifest(packageName)); });
  92. }
  93. }
  94. private void CreateDownloader(string packageName)
  95. {
  96. int downloadingMaxNum = 10;
  97. int failedTryAgain = 3;
  98. ResourcePackage package = YooAssets.GetPackage(packageName);
  99. var downloaderOperation = package.CreateResourceDownloader(new string[] { "preload", "dynamic" }, downloadingMaxNum, failedTryAgain);
  100. if (downloaderOperation.TotalDownloadCount == 0)
  101. {
  102. LauncherController.OnVersionCompleted();
  103. }
  104. else
  105. {
  106. //A total of 10 files were found that need to be downloaded
  107. Debug.Log($"Found total {downloaderOperation.TotalDownloadCount} files that need download !");
  108. // 发现新更新文件后,挂起流程系统
  109. // 注意:开发者需要在下载前检测磁盘空间不足
  110. int totalDownloadCount = downloaderOperation.TotalDownloadCount;
  111. long totalDownloadBytes = downloaderOperation.TotalDownloadBytes;
  112. float sizeMB = totalDownloadBytes / 1048576f;
  113. sizeMB = Mathf.Clamp(sizeMB, 0.1f, float.MaxValue);
  114. string totalSizeMB = sizeMB.ToString("f1");
  115. string message = $"游戏有新的内容,{packageName}需要更新{totalSizeMB}MB大小的内容";
  116. Alert.Show(message)
  117. .SetLeftButton(true, "更新", (data) =>
  118. {
  119. StartCoroutine(BeginDownload(downloaderOperation, packageName));
  120. });
  121. }
  122. }
  123. private IEnumerator BeginDownload(ResourceDownloaderOperation downloaderOperation, string packageName)
  124. {
  125. // 注册下载回调
  126. downloaderOperation.OnDownloadErrorCallback =
  127. (fileName, error) =>
  128. {
  129. Debug.LogError($"加载{fileName}失败 {error}");
  130. };
  131. downloaderOperation.OnDownloadProgressCallback =
  132. (totalDownloadCount, currentDownloadCount, totalDownloadSizeBytes, currentDownloadSizeBytes) =>
  133. {
  134. string currentSizeMB = (currentDownloadSizeBytes / 1048576f).ToString("f1");
  135. string totalSizeMB = (totalDownloadSizeBytes / 1048576f).ToString("f1");
  136. var progress = (float)currentDownloadSizeBytes / totalDownloadSizeBytes;
  137. LauncherView.Instance.SetDesc($"正在下载资源,{currentDownloadCount}/{totalDownloadCount}", $"{currentSizeMB}MB/{totalSizeMB}MB", true);
  138. LauncherView.Instance.SetProgress((int)(progress * 100));
  139. };
  140. downloaderOperation.BeginDownload();
  141. yield return downloaderOperation;
  142. // 检测下载结果
  143. if (downloaderOperation.Status != EOperationStatus.Succeed)
  144. {
  145. Alert.Show("下载失败!请检查网络状态后重试。")
  146. .SetLeftButton(true, "重试", (data) =>
  147. {
  148. StartCoroutine(BeginDownload(downloaderOperation, packageName));
  149. });
  150. yield break;
  151. }
  152. LauncherController.OnVersionCompleted();
  153. }
  154. /// <summary>
  155. /// 获取资源服务器地址
  156. /// </summary>
  157. private string GetHostServerURL(string packageName)
  158. {
  159. string hostServerIP = "http://10.108.64.127";
  160. #if UNITY_EDITOR
  161. if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
  162. return $"{hostServerIP}/CDN/Android/{packageName}";
  163. else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
  164. return $"{hostServerIP}/CDN/IPhone/{packageName}";
  165. else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
  166. return $"{hostServerIP}/CDN/WebGL/{packageName}";
  167. else
  168. return $"{hostServerIP}/CDN/PC/{packageName}";
  169. #else
  170. if (Application.platform == RuntimePlatform.Android)
  171. return $"{hostServerIP}/CDN/Android/{packageName}";
  172. else if (Application.platform == RuntimePlatform.IPhonePlayer)
  173. return $"{hostServerIP}/CDN/IPhone/{packageName}";
  174. else if (Application.platform == RuntimePlatform.WebGLPlayer)
  175. return $"{hostServerIP}/CDN/WebGL/{packageName}";
  176. else
  177. return $"{hostServerIP}/CDN/PC/{packageName}";
  178. #endif
  179. }
  180. /// <summary>
  181. /// 远端资源地址查询服务类
  182. /// </summary>
  183. private class RemoteServices : IRemoteServices
  184. {
  185. private readonly string _defaultHostServer;
  186. private readonly string _fallbackHostServer;
  187. public RemoteServices(string defaultHostServer, string fallbackHostServer)
  188. {
  189. _defaultHostServer = defaultHostServer;
  190. _fallbackHostServer = fallbackHostServer;
  191. }
  192. string IRemoteServices.GetRemoteMainURL(string fileName)
  193. {
  194. return $"{_defaultHostServer}/{fileName}";
  195. }
  196. string IRemoteServices.GetRemoteFallbackURL(string fileName)
  197. {
  198. return $"{_fallbackHostServer}/{fileName}";
  199. }
  200. }
  201. }
  202. }