SUpdateManager.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace SFramework
  5. {
  6. enum Update_State {
  7. usInvaild,
  8. usStart,
  9. usShowUI,
  10. usHotfixLua,
  11. usGetResVersion,
  12. usCalcUpdateResInfo,
  13. usDownloadResource,
  14. usFinish,
  15. }
  16. public class SUpdateManager : MonoBehaviour
  17. {
  18. private Update_State _currentState;
  19. private GameObject _logicInstance;
  20. private SUIPanelUpdate _uiPanelUpdate;
  21. private SUIPanelTips _uiPanelTips;
  22. private SVersionInfo _localResVersion, _remoteResVersion;
  23. private int _willDownloadBytes;
  24. private List<SFileInfo> _willDownloadFileInfoList = new List<SFileInfo>();
  25. void Awake()
  26. {
  27. _currentState = Update_State.usStart;
  28. Debug.Log("Application.dataPath -> " + Application.dataPath);
  29. Debug.Log("Application.streamingAssetsPath -> " + Application.streamingAssetsPath);
  30. Debug.Log("Application.persistentDataPath -> " + Application.persistentDataPath);
  31. _logicInstance = GameObject.Find("LogicInstance");
  32. Debug.Assert(_logicInstance != null);
  33. }
  34. void Start()
  35. {
  36. _currentState = Update_State.usShowUI;
  37. ShowUpdateUI();
  38. AddUIController();
  39. #pragma warning disable 0162
  40. _currentState = Update_State.usHotfixLua;
  41. if (!SFrameworkDef.isEnableHotfix) _currentState = Update_State.usFinish;
  42. #pragma warning restore
  43. TryUpdate();
  44. }
  45. private void ShowUpdateUI()
  46. {
  47. // Add CanvasUI
  48. GameObject canvasUpdate = SResourceManager.LoadResource("prefabs/canvas_update.prefab") as GameObject;
  49. GameObject.Instantiate(canvasUpdate);
  50. }
  51. private void AddUIController()
  52. {
  53. // Add UIController
  54. _uiPanelUpdate = _logicInstance.AddComponent<SUIPanelUpdate>();
  55. _uiPanelTips = _logicInstance.AddComponent<SUIPanelTips>();
  56. }
  57. public void TryUpdate()
  58. {
  59. StartCoroutine(UpdateLogic());
  60. }
  61. public void UpdateStateInfo(string stateInfo)
  62. {
  63. Debug.Log("SUpdateManager -> " + stateInfo);
  64. _uiPanelUpdate.SetUpdateInfo(stateInfo);
  65. }
  66. IEnumerator UpdateLogic()
  67. {
  68. yield return null;
  69. switch (_currentState)
  70. {
  71. case Update_State.usHotfixLua:
  72. StartCoroutine(TryHotfixLuaLogic());
  73. break;
  74. case Update_State.usGetResVersion:
  75. StartCoroutine(TryGetResVersionLogic());
  76. break;
  77. case Update_State.usCalcUpdateResInfo:
  78. StartCoroutine(TryCalcUpdateResInfoLogic());
  79. break;
  80. case Update_State.usDownloadResource:
  81. StartCoroutine(TryDownloadResource());
  82. break;
  83. case Update_State.usFinish:
  84. StartCoroutine(TryFinishLogic());
  85. break;
  86. default:
  87. Debug.Assert(false, "Update_State Error -> " + _currentState.ToString());
  88. break;
  89. }
  90. yield return new WaitForSeconds(1.0f);
  91. // string resourceVersionURL = SFrameworkDef.resourceVersionUrl;
  92. // Step 3 : Switch To Start Scene.
  93. }
  94. IEnumerator TryHotfixLuaLogic()
  95. {
  96. // Step 1 : Try Hotfix.
  97. yield return null;
  98. UpdateStateInfo("Communication With Server ...");
  99. yield return new WaitForSeconds(1.0f);
  100. string hotfixLuaUrl = SFrameworkDef.hotfixLuaUrl;
  101. UnityEngine.Networking.UnityWebRequest luaRequest =
  102. UnityEngine.Networking.UnityWebRequest.Get(hotfixLuaUrl);
  103. luaRequest.timeout = SFrameworkDef.httpRequestTimeoutTime;
  104. yield return luaRequest.SendWebRequest();
  105. //if (luaRequest.isNetworkError || luaRequest.isHttpError)
  106. if (luaRequest.result == UnityEngine.Networking.UnityWebRequest.Result.ConnectionError || luaRequest.result == UnityEngine.Networking.UnityWebRequest.Result.ProtocolError)
  107. {
  108. Debug.LogError("SUpdateManager -> UpdateLogic luaRequest Error -> " + luaRequest.error);
  109. UpdateStateInfo("Communication With Server ... Error: " + luaRequest.error);
  110. // show tips and notice try again.
  111. _uiPanelTips.ShowTips(
  112. "Connect Failed",
  113. "Connection To Server Failed!\nPlease Check Your Network State.\nClick Yes Try Again. Click No Exit Game.",
  114. delegate(){
  115. Debug.Log("SUpdateManager -> Click Tips Yes -> TryUpdate Again!");
  116. TryUpdate();
  117. },
  118. delegate(){
  119. Debug.Log("SUpdateManager -> Click Tips No -> Exit Game!");
  120. Application.Quit();
  121. }
  122. );
  123. yield break;
  124. }
  125. string luaCode = luaRequest.downloadHandler.text;
  126. SLuaEnv.Instance.DoString(luaCode);
  127. UpdateStateInfo("Communication With Server ... Success");
  128. _currentState = Update_State.usGetResVersion;
  129. TryUpdate();
  130. }
  131. IEnumerator TryGetResVersionLogic()
  132. {
  133. // Step 2 : Try Get Res Version Info And Check IsNeed Update Resource.
  134. yield return null;
  135. UpdateStateInfo("Commuication With Resource Server ...");
  136. yield return new WaitForSeconds(1.0f);
  137. string platformName = SPlatformInfo.GetBuildPlatformName();
  138. string resVersionUrl = SFrameworkDef.resourceVersionUrlBase + platformName + "/" + SFrameworkDef.resourceVersionName;
  139. UnityEngine.Networking.UnityWebRequest resVersionRequest =
  140. UnityEngine.Networking.UnityWebRequest.Get(resVersionUrl);
  141. resVersionRequest.timeout = SFrameworkDef.httpRequestTimeoutTime;
  142. yield return resVersionRequest.SendWebRequest();
  143. if (resVersionRequest.result == UnityEngine.Networking.UnityWebRequest.Result.ConnectionError || resVersionRequest.result == UnityEngine.Networking.UnityWebRequest.Result.ProtocolError)
  144. {
  145. Debug.LogError("SUpdateManager -> UpdateLogic resVersionRequest Error -> " + resVersionRequest.error);
  146. UpdateStateInfo("Communication With Resource Server ... Error: " + resVersionRequest.error);
  147. // show tips and notice try again.
  148. _uiPanelTips.ShowTips(
  149. "Connect Failed",
  150. "Connection To Resrouce Server Failed!\nPlease Check Your Network State.\nClick Yes Try Again. Click No Exit Game.",
  151. delegate() {
  152. Debug.Log("SUpdateManager -> Click Tips Yes -> Try Again!");
  153. TryUpdate();
  154. },
  155. delegate() {
  156. Debug.Log("SUpdateManager -> Click Tips No -> Exit Game!");
  157. Application.Quit();
  158. }
  159. );
  160. yield break;
  161. }
  162. // get version.json success start to calc download files info.
  163. string versionJson = resVersionRequest.downloadHandler.text;
  164. Debug.Log("remoteVersionJson -> " + versionJson);
  165. yield return new WaitForSeconds(1.0f);
  166. SVersionInfo remoteVersion = LitJson.JsonMapper.ToObject<SVersionInfo>(versionJson);
  167. // Debug.Log("Remote Version -> " + remoteVersionInfo.version);
  168. SVersionInfo localVersion = SResourceManager.GetLocalVersionInfo();
  169. // Debug.Log("Local Version -> " + localVersionInfo.version);
  170. UpdateStateInfo(string.Format("Remote Version: {0} Local Version: {1}", remoteVersion.version, localVersion.version));
  171. yield return new WaitForSeconds(1.0f);
  172. _localResVersion = localVersion;
  173. _remoteResVersion = remoteVersion;
  174. yield return new WaitForSeconds(1.0f);
  175. UpdateStateInfo("Commuication With Resource Server ... Success");
  176. _currentState = Update_State.usCalcUpdateResInfo;
  177. if (localVersion.version == remoteVersion.version)
  178. {
  179. // No need to update resource.
  180. _currentState = Update_State.usFinish;
  181. }
  182. // Debug.Log("currentState -> " + currentState.ToString());
  183. TryUpdate();
  184. }
  185. IEnumerator TryCalcUpdateResInfoLogic()
  186. {
  187. // Step 3: Try Update Resource By LocalVersionInfo And RemoteVersionInfo.
  188. yield return null;
  189. UpdateStateInfo("Prepare Calc Update Resource ...");
  190. // Get Update File Count And File Total Size And Update FileInfoList.
  191. Debug.Assert(_localResVersion != null, "TryUpdateResourceLogic -> localResVersion = null");
  192. Debug.Assert(_remoteResVersion != null, "TryUpdateResourceLogic -> remoteResVersion = null");
  193. Debug.Assert(_localResVersion.version != _remoteResVersion.version, "TryUpdateResourceLogic -> LVersion == RVersion");
  194. foreach (SFileInfo oneFileInfo in _remoteResVersion.fileInfo)
  195. {
  196. SFileInfo localFileInfo = _localResVersion.fileInfo.Find(target =>
  197. {
  198. if (target.fileName == oneFileInfo.fileName)
  199. return true;
  200. else
  201. return false;
  202. }
  203. );
  204. // File Existed And Don't Need Update.
  205. if (localFileInfo != null && localFileInfo.hashInfo == oneFileInfo.hashInfo)
  206. continue;
  207. // File Is Not Existed Or Need Update.
  208. _willDownloadBytes += oneFileInfo.fileSize;
  209. _willDownloadFileInfoList.Add(oneFileInfo);
  210. }
  211. UpdateStateInfo("Prepare Calc Update Resource ... Success");
  212. // Show Tips For Player.
  213. // If Choose No Exit Game.
  214. // If Choose Yes Start Update Resource.
  215. _uiPanelTips.ShowTips(
  216. "UpdateInfo",
  217. string.Format(
  218. "Found new version:{0} ...\nFile Count:{1} FileSize:{2}",
  219. _remoteResVersion.version, _willDownloadFileInfoList.Count,
  220. System.Math.Round(_willDownloadBytes / 1024f / 1024f, 2) + "MB"
  221. ),
  222. delegate () {
  223. Debug.Log("SUpdateManager -> Click Tips Yes -> Start Download Logic");
  224. _currentState = Update_State.usDownloadResource;
  225. TryUpdate();
  226. },
  227. delegate () {
  228. Debug.Log("SUpdateManager -> Click Tips No -> Exit Game");
  229. Application.Quit();
  230. }
  231. );
  232. }
  233. IEnumerator TryDownloadResource()
  234. {
  235. // UnityWebRequest.GetAssetBundle(string url, int version, uint crc)
  236. // If crc is not zero, engine will compare crc.
  237. // UnityEngine.Networking.UnityWebRequest.GetAssetBundle("", 0, 0);
  238. yield return null;
  239. UpdateStateInfo("Prepare To Clean Local Resources ...");
  240. yield return new WaitForSeconds(1.0f);
  241. // Download Resource Logic Start:
  242. // Step 1: Try To Delete All Local File(PersistentPath) That Need Update.
  243. int cleanedCount = 1;
  244. int fileTotalCount = _willDownloadFileInfoList.Count;
  245. foreach (SFileInfo oneFileInfo in _willDownloadFileInfoList)
  246. {
  247. SResourceManager.TryDeleteAssetBundle(oneFileInfo.fileName);
  248. UpdateStateInfo(string.Format(
  249. "Clean Local Files({0}/{1}) -> {2}", cleanedCount, fileTotalCount, oneFileInfo.fileName
  250. ));
  251. _uiPanelUpdate.SetProgressPercent(cleanedCount * 1.0f / fileTotalCount);
  252. cleanedCount++;
  253. yield return new WaitForSeconds(1.0f);
  254. }
  255. UpdateStateInfo("Clean All Local Resources ... Success");
  256. yield return new WaitForSeconds(1.0f);
  257. // Step 2: Download Each File One By One And Write It On Right Path.
  258. UpdateStateInfo("Prepare To Download Remote Resources ...");
  259. float downloadStartTime = UnityEngine.Time.realtimeSinceStartup;
  260. float downloadedBytes = 0.0f;
  261. string downloadSpeed = "";
  262. foreach (SFileInfo oneFileInfo in _willDownloadFileInfoList)
  263. {
  264. float baseDownloadedBytes = downloadedBytes;
  265. string platformName = SPlatformInfo.GetBuildPlatformName();
  266. string downloadLink = SFrameworkDef.resourceVersionUrlBase + platformName + "/" + oneFileInfo.fileName;
  267. UnityEngine.Networking.UnityWebRequest resDownloadRequest =
  268. // UnityEngine.Networking.UnityWebRequest.GetAssetBundle(downloadLink, (uint)remoteResVersion.version, 0);
  269. UnityEngine.Networking.UnityWebRequest.Get(downloadLink);
  270. float downloadPercent = 0.0f;
  271. _uiPanelUpdate.SetProgressPercent(downloadPercent);
  272. resDownloadRequest.SendWebRequest();
  273. while (!resDownloadRequest.isDone)
  274. {
  275. downloadPercent = resDownloadRequest.downloadProgress * 100.0f;
  276. if (downloadPercent < 0) downloadPercent = 0;
  277. System.Math.Round(downloadPercent, 2);
  278. float fileDownloadBytes = baseDownloadedBytes + resDownloadRequest.downloadedBytes;
  279. downloadSpeed = SToolFunction.GetDownloadSpeed(fileDownloadBytes, UnityEngine.Time.realtimeSinceStartup - downloadStartTime);
  280. UpdateStateInfo(string.Format("Downloading: {0} From {1} \nPercent: {2} Speed:{3}",
  281. oneFileInfo.fileName, downloadLink, downloadPercent, downloadSpeed
  282. ));
  283. _uiPanelUpdate.SetProgressPercent(downloadPercent);
  284. yield return null;
  285. }
  286. _uiPanelUpdate.SetProgressPercent(1.0f);
  287. downloadedBytes += resDownloadRequest.downloadedBytes;
  288. downloadSpeed = SToolFunction.GetDownloadSpeed(downloadedBytes, UnityEngine.Time.realtimeSinceStartup - downloadStartTime);
  289. UpdateStateInfo(string.Format("Downloading: {0} \nPercent: {1} Speed:{2} Success", oneFileInfo.fileName, downloadPercent, downloadSpeed));
  290. yield return new WaitForSeconds(1.0f);
  291. SResourceManager.SaveAssetBundle(oneFileInfo.fileName, resDownloadRequest.downloadHandler.data);
  292. UpdateStateInfo(string.Format("Download And Save {0} Success", oneFileInfo.fileName));
  293. yield return new WaitForSeconds(1.0f);
  294. }
  295. downloadSpeed = SToolFunction.GetDownloadSpeed(downloadedBytes, UnityEngine.Time.realtimeSinceStartup - downloadStartTime);
  296. UpdateStateInfo("All Remote Resource Download Compelete ... Speed:" + downloadSpeed);
  297. // Step 3: Try Write version.json(Remote Version) To PersistentPath.
  298. SResourceManager.SaveRemoteVersion(_remoteResVersion);
  299. // Step 4: Change currentState And Call TryUpdate().
  300. UpdateStateInfo("All Files Download Finish ...");
  301. yield return new WaitForSeconds(1.0f);
  302. _currentState = Update_State.usFinish;
  303. TryUpdate();
  304. }
  305. IEnumerator TryFinishLogic()
  306. {
  307. // Step 4: Try To Switch Scene To Start.unity.
  308. yield return null;
  309. UpdateStateInfo("All Data Updated ... Success");
  310. yield return new WaitForSeconds(1.0f);
  311. yield return new WaitForSeconds(1.0f);
  312. SResourceManager.LoadResource("scenes/start.unity");
  313. UnityEngine.SceneManagement.SceneManager.LoadScene("Start");
  314. }
  315. }
  316. }