using System; using System.Collections; using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; using YooAsset; using ET; using static PatchEventMessageDefine; public static class PatchUpdater { private static bool _isRun = false; private static int _retryCnt = 0; /// /// 下载器 /// public static PatchDownloaderOperation Downloader { set; get; } /// /// 资源版本 /// public static int ResourceVersion { set; get; } private static readonly EventGroup _eventGroup = new EventGroup(); public static Action OnStateUpdate; public static Action OnDownLoadProgressUpdate; private static UniTaskCompletionSource s_UniTaskCompletionSource; public static void InitCallback(Action onStateUpdate, Action onDownLoadProgressUpdate) { OnStateUpdate += onStateUpdate; OnDownLoadProgressUpdate += onDownLoadProgressUpdate; } /// /// 开启初始化流程 /// public static void Run(UniTaskCompletionSource uniTaskCompletionSource) { s_UniTaskCompletionSource = uniTaskCompletionSource; if (_isRun == false) { _isRun = true; _eventGroup.AddListener(OnHandleEvent); _eventGroup.AddListener(OnHandleEvent); _eventGroup.AddListener(OnHandleEvent); _eventGroup.AddListener(OnHandleEvent); _eventGroup.AddListener(OnHandleEvent); _eventGroup.AddListener(OnHandleEvent); // 注意:按照先后顺序添加流程节点 FsmManager.AddNode(new FsmPatchInit()); FsmManager.AddNode(new FsmUpdateStaticVersion()); FsmManager.AddNode(new FsmUpdateManifest()); FsmManager.AddNode(new FsmCreateDownloader()); FsmManager.AddNode(new FsmDownloadWebFiles()); FsmManager.AddNode(new FsmPatchDone()); FsmManager.Run(nameof(FsmPatchInit)); } else { Debug.LogWarning("补丁更新已经正在进行中!"); } } /// /// 处理请求操作 /// private static void HandleOperation(EPatchOperation operation) { if (operation == EPatchOperation.BeginDownloadWebFiles) { FsmManager.Transition(nameof(FsmDownloadWebFiles)); } else if (operation == EPatchOperation.TryUpdateStaticVersion) { FsmManager.Transition(nameof(FsmUpdateStaticVersion)); } else if (operation == EPatchOperation.TryUpdatePatchManifest) { FsmManager.Transition(nameof(FsmUpdateManifest)); } else if (operation == EPatchOperation.TryDownloadWebFiles) { FsmManager.Transition(nameof(FsmCreateDownloader)); } else { throw new NotImplementedException($"{operation}"); } } /// /// 接收事件 /// private static void OnHandleEvent(IEventMessage msg) { if (msg is PatchEventMessageDefine.PatchStatesChange patchStatesChange) { if (patchStatesChange.CurrentStates == EPatchStates.UpdateStaticVersion) Log.Info("Update static version."); else if (patchStatesChange.CurrentStates == EPatchStates.UpdateManifest) Log.Info("Update patch manifest."); else if (patchStatesChange.CurrentStates == EPatchStates.CreateDownloader) Log.Info("Check download contents."); else if (patchStatesChange.CurrentStates == EPatchStates.DownloadWebFiles) Log.Info("Downloading patch files."); else if (patchStatesChange.CurrentStates == EPatchStates.PatchDone) { s_UniTaskCompletionSource?.TrySetResult(); Log.Info("PatchDone. "); } else throw new NotImplementedException(patchStatesChange.CurrentStates.ToString()); OnStateUpdate?.Invoke(patchStatesChange); } else if (msg is PatchEventMessageDefine.FoundUpdateFiles) { var message = msg as PatchEventMessageDefine.FoundUpdateFiles; float sizeMB = message.TotalSizeBytes / 1048576f; sizeMB = Mathf.Clamp(sizeMB, 0.1f, float.MaxValue); string totalSizeMB = sizeMB.ToString("f1"); ET.Log.Info($"Found update patch files, Total count {message.TotalCount} Total szie {totalSizeMB}MB"); PatchUpdater.HandleOperation(EPatchOperation.BeginDownloadWebFiles); } else if (msg is PatchEventMessageDefine.DownloadProgressUpdate downloadProgressUpdate) { OnDownLoadProgressUpdate?.Invoke(downloadProgressUpdate); } else if (msg is PatchEventMessageDefine.StaticVersionUpdateFailed) { ET.Log.Error($"Failed to update static version, please check the network status."); ErrorRetry(EPatchOperation.TryUpdateStaticVersion); } else if (msg is PatchEventMessageDefine.PatchManifestUpdateFailed) { ET.Log.Error($"Failed to update patch manifest, please check the network status."); ErrorRetry(EPatchOperation.TryUpdatePatchManifest); } else if (msg is PatchEventMessageDefine.WebFileDownloadFailed) { var message = msg as PatchEventMessageDefine.WebFileDownloadFailed; ET.Log.Error($"Failed to download file : {message.FileName}"); ErrorRetry(EPatchOperation.TryDownloadWebFiles); } else { throw new System.NotImplementedException($"{msg.GetType()}"); } } private static void ErrorRetry(EPatchOperation operation) { if (++_retryCnt >= 2) { Log.Warning($"Retry {_retryCnt} times, Abort."); s_UniTaskCompletionSource?.TrySetResult(); var state = new PatchStatesChange(); state.CurrentStates = EPatchStates.PatchDone; OnStateUpdate?.Invoke(state); } else { PatchUpdater.HandleOperation(operation); } } }