BITKit/Packages/Runtime~/Unity/Scripts/Application/ApplicationService.cs

182 lines
5.5 KiB
C#

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<string> OnClientVersionCheck
{
add => ApplicationService.OnClientVersionCheck += value;
remove => ApplicationService.OnClientVersionCheck -= value;
}
public event Action<string> OnLatestVersionCheck
{
add => ApplicationService.OnLatestVersionCheck += value;
remove => ApplicationService.OnLatestVersionCheck -= value;
}
public event Action<string> OnDownloadLatest
{
add => ApplicationService.OnDownloadLatest += value;
remove => ApplicationService.OnDownloadLatest -= value;
}
public event Action<float> OnDownloadProgress
{
add => ApplicationService.OnDownloadProgress += value;
remove => ApplicationService.OnDownloadProgress -= value;
}
public event Action<string> OnDownloadComplete
{
add => ApplicationService.OnDownloadComplete += value;
remove => ApplicationService.OnDownloadComplete -= value;
}
public UniTask<string> DownloadLatestVersionAsync()
{
return _applicationServiceImplementation.DownloadLatestVersionAsync();
}
public string DownloadLatestUrl => _applicationServiceImplementation.DownloadLatestUrl;
public string CheckLatestVersionUrl => _applicationServiceImplementation.CheckLatestVersionUrl;
}
/// <summary>
/// 用于Unity的应用程序服务,详细功能请查看<see cref="IApplicationService"/>
/// </summary>
public class ApplicationService : MonoBehaviour,IApplicationService
{
public static event Action<string> OnClientVersionCheck;
public static event Action<string> OnLatestVersionCheck;
public static event Action<string> OnDownloadLatest;
public static event Action<float> OnDownloadProgress;
public static event Action<string> 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<string> IApplicationService.OnClientVersionCheck
{
add => OnClientVersionCheck += value;
remove => OnClientVersionCheck -= value;
}
event Action<string> IApplicationService.OnLatestVersionCheck
{
add => OnLatestVersionCheck += value;
remove => OnLatestVersionCheck -= value;
}
event Action<string> IApplicationService.OnDownloadLatest
{
add => OnDownloadLatest += value;
remove => OnDownloadLatest -= value;
}
event Action<float> IApplicationService.OnDownloadProgress
{
add => OnDownloadProgress += value;
remove => OnDownloadProgress -= value;
}
event Action<string> IApplicationService.OnDownloadComplete
{
add => OnDownloadComplete += value;
remove => OnDownloadComplete -= value;
}
private UnityWebRequest downloadRequest;
private CancellationTokenSource _cancellationTokenSource;
public async UniTask<string> 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<ApplicationService>($"开始下载最新版本,下载地址:{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<ApplicationService>(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();
}
}
}