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);
}
}
}