VersionController.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using GFGGame.Launcher;
  2. using System;
  3. using System.Collections;
  4. using UnityEngine;
  5. using YooAsset;
  6. namespace GFGGame
  7. {
  8. public class VersionController : SingletonMonoBase<VersionController>
  9. {
  10. public const string DefaultPackage = "GameLogic";
  11. string defaultHostServer = "http://127.0.0.1/CDN/Android/v1.0";
  12. string fallbackHostServer = "http://127.0.0.1/CDN/Android/v1.0";
  13. public ResourcePackage package;
  14. /// <summary>
  15. /// 包裹的版本信息
  16. /// </summary>
  17. public string PackageVersion { set; get; }
  18. public void Init()
  19. {
  20. // 初始化资源系统
  21. YooAssets.Initialize();
  22. StartCoroutine(InitVersion());
  23. }
  24. public IEnumerator InitVersion()
  25. {
  26. yield return InitDefaultPackage();
  27. if (string.IsNullOrEmpty(LauncherConfig.manifest_v))
  28. {
  29. var cor = StartCoroutine(GetStaticVersion(DefaultPackage));
  30. yield return cor;
  31. }
  32. else
  33. {
  34. VersionController.Instance.PackageVersion = LauncherConfig.manifest_v;
  35. }
  36. yield return UpdateManifest(DefaultPackage);
  37. CreateDownloader(DefaultPackage);
  38. }
  39. private IEnumerator InitDefaultPackage()
  40. {
  41. // 创建默认的资源包
  42. //string packageName = DefaultPackage;
  43. //var package = YooAssets.TryGetPackage(packageName);
  44. //Debug.Log($"是否找到包:{package}");
  45. //if (package == null)
  46. //{
  47. // package = YooAssets.CreatePackage(packageName);
  48. // YooAssets.SetDefaultPackage(package);
  49. //}
  50. package = YooAssets.CreatePackage(DefaultPackage);
  51. YooAssets.SetDefaultPackage(package);
  52. var playMode = GameLauncher.Instance.PlayMode;
  53. #if UNITY_EDITOR
  54. #elif UNITY_WEBGL
  55. playMode = EPlayMode.WebPlayMode;
  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. var buildResult = EditorSimulateModeHelper.SimulateBuild(DefaultPackage);
  65. var packageRoot = buildResult.PackageRootDirectory;
  66. var fileSystemParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
  67. var createParameters = new EditorSimulateModeParameters();
  68. createParameters.EditorFileSystemParameters = fileSystemParams;
  69. initializationOperation = package.InitializeAsync(createParameters);
  70. yield return initializationOperation;
  71. if (initializationOperation.Status == EOperationStatus.Succeed)
  72. Debug.Log("资源包初始化成功!");
  73. else
  74. Debug.LogError($"资源包初始化失败:{initializationOperation.Error}");
  75. }
  76. else if (playMode == EPlayMode.HostPlayMode)
  77. {
  78. // 联机运行模式
  79. //string defaultHostServer = GetHostServerURL(DefaultPackage);
  80. //string fallbackHostServer = defaultHostServer;
  81. //var createParameters = new HostPlayModeParameters();
  82. //createParameters.DecryptionServices = new GameDecryptionServices();
  83. //createParameters.QueryServices = new GameQueryServices();
  84. //createParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
  85. //initializationOperation = package.InitializeAsync(createParameters);
  86. var fileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
  87. var createParameters = new OfflinePlayModeParameters();
  88. createParameters.BuildinFileSystemParameters = fileSystemParams;
  89. initializationOperation = package.InitializeAsync(createParameters);
  90. yield return initializationOperation;
  91. if (initializationOperation.Status == EOperationStatus.Succeed)
  92. Debug.Log("资源包初始化成功!");
  93. else
  94. Debug.LogError($"资源包初始化失败:{initializationOperation.Error}");
  95. }
  96. else if (playMode == EPlayMode.HostPlayMode)
  97. {
  98. IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
  99. var cacheFileSystemParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
  100. var buildinFileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
  101. var createParameters = new HostPlayModeParameters();
  102. createParameters.BuildinFileSystemParameters = buildinFileSystemParams;
  103. createParameters.CacheFileSystemParameters = cacheFileSystemParams;
  104. initializationOperation = package.InitializeAsync(createParameters);
  105. yield return initializationOperation;
  106. if (initializationOperation.Status == EOperationStatus.Succeed)
  107. Debug.Log("资源包初始化成功!");
  108. else
  109. Debug.LogError($"资源包初始化失败:{initializationOperation.Error}");
  110. }
  111. else if (playMode == EPlayMode.WebPlayMode)
  112. {
  113. Debug.Log("进入EPlayMode.WebPlayMode");
  114. defaultHostServer = Application.streamingAssetsPath + "\\yoo\\GameLogic\\";
  115. fallbackHostServer = Application.streamingAssetsPath + "\\yoo\\GameLogic\\";
  116. IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
  117. //var webServerFileSystemParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
  118. var webRemoteFileSystemParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载
  119. var createParameters = new WebPlayModeParameters();
  120. //createParameters.WebServerFileSystemParameters = webServerFileSystemParams;
  121. createParameters.WebRemoteFileSystemParameters = webRemoteFileSystemParams;
  122. initializationOperation = package.InitializeAsync(createParameters);
  123. yield return initializationOperation;
  124. if (initializationOperation.Status == EOperationStatus.Succeed)
  125. Debug.Log("资源包初始化成功!");
  126. else
  127. Debug.LogError($"资源包初始化失败:{initializationOperation.Error}");
  128. }
  129. yield return initializationOperation;
  130. if (initializationOperation.Status != EOperationStatus.Succeed)
  131. {
  132. Debug.LogWarning($"{initializationOperation.Error}");
  133. }
  134. }
  135. private IEnumerator GetStaticVersion(string packageName)
  136. {
  137. //var package = YooAssets.GetPackage(packageName);
  138. Debug.Log(package.PackageName);
  139. //var operation = package.UpdatePackageVersionAsync();
  140. var operation = package.RequestPackageVersionAsync();
  141. yield return operation;
  142. if (operation.Status == EOperationStatus.Succeed)
  143. {
  144. VersionController.Instance.PackageVersion = operation.PackageVersion;
  145. Debug.Log($"远端最新版本为: {operation.PackageVersion}");
  146. }
  147. else
  148. {
  149. Debug.LogWarning(operation.Error);
  150. }
  151. }
  152. private IEnumerator UpdateManifest(string packageName)
  153. {
  154. bool savePackageVersion = true;
  155. //var package = YooAssets.GetPackage(packageName);
  156. var operation =
  157. package.UpdatePackageManifestAsync(VersionController.Instance.PackageVersion);
  158. //package.UpdatePackageManifestAsync(VersionController.Instance.PackageVersion, savePackageVersion);
  159. yield return operation;
  160. if (operation.Status != EOperationStatus.Succeed)
  161. {
  162. Debug.LogWarning(operation.Error);
  163. Alert.Show("更新版本信息失败,请检测网络链接后重试。")
  164. .SetLeftButton(true, "重试", (data) => { StartCoroutine(UpdateManifest(packageName)); });
  165. }
  166. }
  167. private void CreateDownloader(string packageName)
  168. {
  169. LauncherController.OnVersionCompleted();
  170. return;
  171. int downloadingMaxNum = 10;
  172. int failedTryAgain = 3;
  173. // ResourcePackage package = YooAssets.GetPackage(packageName);
  174. //ResourceDownloaderOperation downloaderOperation = package.CreateResourceDownloader(new string[] { "preload", "dynamic" }, downloadingMaxNum, failedTryAgain);
  175. ResourceDownloaderOperation downloaderOperation =
  176. package.CreateResourceDownloader(new string[] { "preload" }, downloadingMaxNum, failedTryAgain);
  177. if (downloaderOperation.TotalDownloadCount == 0)
  178. {
  179. LauncherController.OnVersionCompleted();
  180. }
  181. else
  182. {
  183. //A total of 10 files were found that need to be downloaded
  184. Debug.Log($"Found total {downloaderOperation.TotalDownloadCount} files that need download !");
  185. // 发现新更新文件后,挂起流程系统
  186. // 注意:开发者需要在下载前检测磁盘空间不足
  187. //int totalDownloadCount = downloaderOperation.TotalDownloadCount;
  188. long totalDownloadBytes = downloaderOperation.TotalDownloadBytes;
  189. float sizeMB = totalDownloadBytes / 1048576f;
  190. sizeMB = Mathf.Clamp(sizeMB, 0.1f, float.MaxValue);
  191. if (sizeMB > LauncherConfig.promptSizeMB)
  192. {
  193. string totalSizeMB = sizeMB.ToString("f1");
  194. if (string.IsNullOrEmpty(LauncherConfig.updateResPrompt))
  195. {
  196. LauncherConfig.updateResPrompt = "游戏有新的内容,需要更新{0}MB大小的资源";
  197. }
  198. string message = string.Format(LauncherConfig.updateResPrompt, totalSizeMB);
  199. Alert.Show(message)
  200. .SetLeftButton(true, "更新",
  201. (data) => { StartCoroutine(BeginDownload(downloaderOperation, packageName)); });
  202. }
  203. else
  204. {
  205. StartCoroutine(BeginDownload(downloaderOperation, packageName));
  206. }
  207. }
  208. }
  209. private IEnumerator BeginDownload(ResourceDownloaderOperation downloaderOperation, string packageName)
  210. {
  211. // 注册下载回调
  212. downloaderOperation.DownloadErrorCallback = (data) => {
  213. Debug.LogError($"" +
  214. $"加载{data.FileName}失败 {data.ErrorInfo}");
  215. };
  216. downloaderOperation.DownloadUpdateCallback = (data) =>
  217. {
  218. //string currentSizeMB = (currentDownloadSizeBytes / 1048576f).ToString("f1");
  219. //string totalSizeMB = (totalDownloadSizeBytes / 1048576f).ToString("f1");
  220. //var progress = (float)currentDownloadSizeBytes / totalDownloadSizeBytes;
  221. //LauncherView.Instance.SetDesc($"正在下载资源,{currentDownloadCount}/{totalDownloadCount}",
  222. // $"{currentSizeMB}MB/{totalSizeMB}MB", true);
  223. //LauncherView.Instance.SetProgress((int)(progress * 100));
  224. string currentSizeMB = (data.CurrentDownloadBytes / 1048576f).ToString("f1");
  225. string totalSizeMB = (data.TotalDownloadBytes / 1048576f).ToString("f1");
  226. var progress = (float)data.CurrentDownloadBytes / data.TotalDownloadBytes;
  227. LauncherView.Instance.SetDesc($"正在下载资源,{data.CurrentDownloadCount}/{data.TotalDownloadCount}",
  228. $"{currentSizeMB}MB/{totalSizeMB}MB", true);
  229. LauncherView.Instance.SetProgress((int)(progress * 100));
  230. };
  231. downloaderOperation.BeginDownload();
  232. yield return downloaderOperation;
  233. // 检测下载结果
  234. if (downloaderOperation.Status != EOperationStatus.Succeed)
  235. {
  236. Alert.Show("下载失败!请检查网络状态后重试。")
  237. .SetLeftButton(true, "重试",
  238. (data) => { StartCoroutine(BeginDownload(downloaderOperation, packageName)); });
  239. yield break;
  240. }
  241. LauncherController.OnVersionCompleted();
  242. }
  243. /// <summary>
  244. /// 获取资源服务器地址
  245. /// </summary>
  246. private string GetHostServerURL(string packageName)
  247. {
  248. //LauncherConfig.CDN_ROOT = "http://10.108.64.127";
  249. string platform = "PC";
  250. #if UNITY_EDITOR
  251. if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
  252. platform = "Android";
  253. else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
  254. platform = "IOS";
  255. else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
  256. platform = "WebGL";
  257. #else
  258. if (Application.platform == RuntimePlatform.Android)
  259. platform = "Android";
  260. else if (Application.platform == RuntimePlatform.IPhonePlayer)
  261. platform = "IOS";
  262. else if (Application.platform == RuntimePlatform.WebGLPlayer)
  263. platform = "WebGL";
  264. #endif
  265. return $"{LauncherConfig.CDN_ROOT}/{platform}/{packageName}/HostPlay";
  266. }
  267. /// <summary>
  268. /// 远端资源地址查询服务类
  269. /// </summary>
  270. private class RemoteServices : IRemoteServices
  271. {
  272. private readonly string _defaultHostServer;
  273. private readonly string _fallbackHostServer;
  274. public RemoteServices(string defaultHostServer, string fallbackHostServer)
  275. {
  276. _defaultHostServer = defaultHostServer;
  277. _fallbackHostServer = fallbackHostServer;
  278. }
  279. string IRemoteServices.GetRemoteMainURL(string fileName)
  280. {
  281. return $"{_defaultHostServer}/{fileName}";
  282. }
  283. string IRemoteServices.GetRemoteFallbackURL(string fileName)
  284. {
  285. return $"{_fallbackHostServer}/{fileName}";
  286. }
  287. }
  288. }
  289. }