using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Security; using System.Threading; using BITKit.Apps; using BITKit.HttpNet; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.Events; using HttpClient = System.Net.Http.HttpClient; using OperationCanceledException = System.OperationCanceledException; using UnityWebRequest = UnityEngine.Networking.UnityWebRequest; namespace BITKit { [Serializable] public class UnityApplicationServiceSingleton:IApplicationService { private IApplicationService _applicationServiceImplementation=>ApplicationService.Singleton; public event Action OnClientVersionCheck { add => ApplicationService.OnClientVersionCheck += value; remove => ApplicationService.OnClientVersionCheck -= value; } public event Action OnLatestVersionCheck { add => ApplicationService.OnLatestVersionCheck += value; remove => ApplicationService.OnLatestVersionCheck -= value; } public event Action OnDownloadLatest { add => ApplicationService.OnDownloadLatest += value; remove => ApplicationService.OnDownloadLatest -= value; } public event Action OnDownloadProgress { add => ApplicationService.OnDownloadProgress += value; remove => ApplicationService.OnDownloadProgress -= value; } public event Action OnDownloadComplete { add => ApplicationService.OnDownloadComplete += value; remove => ApplicationService.OnDownloadComplete -= value; } public UniTask DownloadLatestVersionAsync() { return _applicationServiceImplementation.DownloadLatestVersionAsync(); } public string DownloadLatestUrl => _applicationServiceImplementation.DownloadLatestUrl; public string CheckLatestVersionUrl => _applicationServiceImplementation.CheckLatestVersionUrl; } /// /// 用于Unity的应用程序服务,详细功能请查看 /// public class ApplicationService : MonoBehaviour,IApplicationService { public static event Action OnClientVersionCheck; public static event Action OnLatestVersionCheck; public static event Action OnDownloadLatest; public static event Action OnDownloadProgress; public static event Action OnDownloadComplete; internal static IApplicationService Singleton { get; private set; } [SerializeField, SerializeReference, SubclassSelector] private IReference getVersionUrl; [SerializeField, SerializeReference, SubclassSelector] private IReference getLatestUrl; [SerializeField, SerializeReference, SubclassSelector] private WebProvider webProvider; event Action IApplicationService.OnClientVersionCheck { add => OnClientVersionCheck += value; remove => OnClientVersionCheck -= value; } event Action IApplicationService.OnLatestVersionCheck { add => OnLatestVersionCheck += value; remove => OnLatestVersionCheck -= value; } event Action IApplicationService.OnDownloadLatest { add => OnDownloadLatest += value; remove => OnDownloadLatest -= value; } event Action IApplicationService.OnDownloadProgress { add => OnDownloadProgress += value; remove => OnDownloadProgress -= value; } event Action IApplicationService.OnDownloadComplete { add => OnDownloadComplete += value; remove => OnDownloadComplete -= value; } private UnityWebRequest downloadRequest; private CancellationTokenSource _cancellationTokenSource; public async UniTask DownloadLatestVersionAsync() { var filePath = $"{Application.persistentDataPath}/{Application.productName}-Build_{Application.platform}_{Application.version}."; switch (Application.platform) { case RuntimePlatform.Android: filePath += "apk"; break; default: filePath += "zip"; break; } BIT4Log.Log($"开始下载最新版本,下载地址:{getLatestUrl.Value},保存路径:{filePath}"); OnDownloadLatest?.Invoke(getLatestUrl.Value); downloadRequest = UnityWebRequest.Get(getLatestUrl.Get()); downloadRequest.SendWebRequest().ToUniTask().Forget(); while (downloadRequest.downloadHandler.isDone is false) { OnDownloadProgress?.Invoke(downloadRequest.downloadProgress); _cancellationTokenSource.Token.ThrowIfCancellationRequested(); await UniTask.NextFrame(); } await File.WriteAllBytesAsync(filePath, downloadRequest.downloadHandler.data,_cancellationTokenSource.Token); OnDownloadComplete?.Invoke(filePath); return filePath; } public string DownloadLatestUrl => getLatestUrl.Value; public string CheckLatestVersionUrl=>getVersionUrl.Value; private void Awake() { Singleton = this; _cancellationTokenSource = new CancellationTokenSource(); } private async void Start() { try { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); var latestVersion = await webProvider.GetAsync(getVersionUrl.Get(), _cancellationTokenSource.Token); var currentVersion = Application.version; BIT4Log.Log(latestVersion != currentVersion ? $"当前版本{currentVersion}不是最新版本{latestVersion},请及时更新" : $"当前版本{currentVersion}是最新版本"); OnClientVersionCheck?.Invoke(currentVersion); OnLatestVersionCheck?.Invoke(latestVersion); } catch(OperationCanceledException){} catch (Exception e) { BIT4Log.LogException(e); } } private void OnDestroy() { downloadRequest?.Abort(); _cancellationTokenSource?.Cancel(); } } }