208 lines
5.9 KiB
C#
208 lines
5.9 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 event Action OnDetectedLatestVersion;
|
|
|
|
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;
|
|
|
|
[SerializeReference, SubclassSelector] private ITicker checkTick;
|
|
[SerializeField] private bool dontDestroyOnLoad;
|
|
|
|
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;
|
|
}
|
|
|
|
public event Action OnDetectedLatestVersion
|
|
{
|
|
add => Singleton.OnDetectedLatestVersion += value;
|
|
remove => Singleton.OnDetectedLatestVersion -= value;
|
|
}
|
|
|
|
private UnityWebRequest downloadRequest;
|
|
|
|
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);
|
|
destroyCancellationToken.ThrowIfCancellationRequested();
|
|
await UniTask.NextFrame();
|
|
}
|
|
|
|
await File.WriteAllBytesAsync(filePath, downloadRequest.downloadHandler.data,destroyCancellationToken);
|
|
OnDownloadComplete?.Invoke(filePath);
|
|
|
|
return filePath;
|
|
}
|
|
|
|
public string DownloadLatestUrl => getLatestUrl.Value;
|
|
public string CheckLatestVersionUrl=>getVersionUrl.Value;
|
|
private bool _isBusy;
|
|
|
|
private void Awake()
|
|
{
|
|
Singleton = this;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (dontDestroyOnLoad)
|
|
{
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
try
|
|
{
|
|
OnTick(0);
|
|
}
|
|
catch(OperationCanceledException){}
|
|
catch (Exception e)
|
|
{
|
|
BIT4Log.LogException(e);
|
|
}
|
|
|
|
destroyCancellationToken.Register(Dispose);
|
|
|
|
checkTick?.Add(OnTick);
|
|
}
|
|
private async void OnTick(float deltaTime)
|
|
{
|
|
if(_isBusy)return;
|
|
try
|
|
{
|
|
var latestVersion = await webProvider.GetAsync(getVersionUrl.Get(), destroyCancellationToken);
|
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
|
|
|
var currentVersion = Application.version;
|
|
|
|
OnClientVersionCheck?.Invoke(currentVersion);
|
|
OnLatestVersionCheck?.Invoke(latestVersion);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
BIT4Log.LogException(e);
|
|
}
|
|
_isBusy = false;
|
|
}
|
|
private void Dispose()
|
|
{
|
|
checkTick?.Remove(OnTick);
|
|
downloadRequest?.Abort();
|
|
}
|
|
}
|
|
|
|
}
|