VersionController.cs 11 KB

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