using System;
|
using UnityEngine;
|
using Cysharp.Threading.Tasks;
|
using UnityEngine.Networking;
|
|
/// <summary>
|
/// 启动工具类,提供版本比较等功能
|
/// </summary>
|
public static class LaunchUtility
|
{
|
/// <summary>
|
/// 版本更新类型
|
/// </summary>
|
public enum UpdateType
|
{
|
None, // 无需更新
|
PatchUpdate, // 小版本更新,更新后可直接进入游戏
|
MinorUpdate, // 中版本更新,更新后需要重启
|
MajorUpdate // 大版本更新,需要重新下载
|
}
|
|
/// <summary>
|
/// 比较版本并返回更新类型
|
/// </summary>
|
/// <param name="localVersion">本地版本字符串,格式为 x.y.z</param>
|
/// <param name="remoteVersion">远程版本字符串,格式为 x.y.z</param>
|
/// <returns>版本更新类型</returns>
|
public static UpdateType CompareVersions(string localVersion, string remoteVersion)
|
{
|
if (string.IsNullOrEmpty(localVersion) || string.IsNullOrEmpty(remoteVersion))
|
{
|
Debug.LogError("版本信息为空,无法比较");
|
return UpdateType.None;
|
}
|
|
try
|
{
|
// 解析本地版本
|
int[] localParts = ParseVersionString(localVersion);
|
int localMajor = localParts[0];
|
int localMinor = localParts[1];
|
int localPatch = localParts[2];
|
|
// 解析远程版本
|
int[] remoteParts = ParseVersionString(remoteVersion);
|
int remoteMajor = remoteParts[0];
|
int remoteMinor = remoteParts[1];
|
int remotePatch = remoteParts[2];
|
|
// 检查大版本
|
if (remoteMajor > localMajor)
|
{
|
return UpdateType.MajorUpdate;
|
}
|
|
// 检查中版本
|
if (remoteMajor == localMajor && remoteMinor > localMinor)
|
{
|
return UpdateType.MinorUpdate;
|
}
|
|
// 检查小版本
|
if (remoteMajor == localMajor && remoteMinor == localMinor && remotePatch > localPatch)
|
{
|
return UpdateType.PatchUpdate;
|
}
|
|
// 无需更新
|
return UpdateType.None;
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"比较版本失败: {e.Message}");
|
return UpdateType.None;
|
}
|
}
|
|
/// <summary>
|
/// 解析版本字符串为整数数组
|
/// </summary>
|
/// <param name="versionString">版本字符串,格式为 x.y.z</param>
|
/// <returns>包含三个整数的数组,分别表示大版本、中版本和小版本</returns>
|
private static int[] ParseVersionString(string versionString)
|
{
|
int[] result = new int[3] { 0, 0, 0 };
|
|
string[] parts = versionString.Split('.');
|
|
// 解析大版本
|
if (parts.Length > 0 && int.TryParse(parts[0], out int major))
|
{
|
result[0] = major;
|
}
|
|
// 解析中版本
|
if (parts.Length > 1 && int.TryParse(parts[1], out int minor))
|
{
|
result[1] = minor;
|
}
|
|
// 解析小版本
|
if (parts.Length > 2 && int.TryParse(parts[2], out int patch))
|
{
|
result[2] = patch;
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 获取本地版本信息
|
/// 适用于安卓、iOS、WebGL和PC平台
|
/// </summary>
|
/// <returns>版本字符串,格式为 x.y.z</returns>
|
public static async UniTask<string> GetLocalVersionAsync()
|
{
|
try
|
{
|
// 首先尝试从Resources加载版本文件
|
TextAsset versionAsset = Resources.Load<TextAsset>("version");
|
|
if (versionAsset != null)
|
{
|
string versionText = versionAsset.text.Trim();
|
Debug.Log($"从Resources加载版本信息: {versionText}");
|
return versionText;
|
}
|
|
// 如果Resources中没有版本文件,则使用应用程序版本
|
string appVersion = Application.version;
|
Debug.Log($"使用应用程序版本: {appVersion}");
|
|
// 确保版本号格式正确
|
if (string.IsNullOrEmpty(appVersion))
|
{
|
Debug.LogWarning("应用程序版本为空,使用默认版本 1.0.0");
|
appVersion = "1.0.0";
|
}
|
|
return appVersion;
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"获取本地版本信息失败: {e.Message}");
|
return "1.0.0"; // 返回默认版本
|
}
|
}
|
|
/// <summary>
|
/// 从URL获取远程版本信息
|
/// </summary>
|
/// <param name="url">远程版本文件URL</param>
|
/// <returns>远程版本字符串</returns>
|
public static async UniTask<string> GetRemoteVersionAsync(string url)
|
{
|
const int maxRetries = 3; // 最大重试次数
|
const float timeoutSeconds = 10f; // 超时时间(秒)
|
|
for (int retry = 0; retry < maxRetries; retry++)
|
{
|
try
|
{
|
using (var cancellationTokenSource = new System.Threading.CancellationTokenSource())
|
{
|
// 设置超时
|
cancellationTokenSource.CancelAfterSlim(TimeSpan.FromSeconds(timeoutSeconds));
|
|
// 使用UnityWebRequest获取远程版本
|
using (UnityWebRequest request = UnityWebRequest.Get(url))
|
{
|
// 发送请求并等待结果,带超时
|
await request.SendWebRequest().WithCancellation(cancellationTokenSource.Token);
|
|
if (request.result == UnityWebRequest.Result.Success)
|
{
|
string versionText = request.downloadHandler.text.Trim();
|
Debug.Log($"成功获取远程版本: {versionText},尝试次数: {retry + 1}");
|
return versionText;
|
}
|
else
|
{
|
Debug.LogWarning($"获取远程版本失败: {request.error},尝试次数: {retry + 1}/{maxRetries}");
|
}
|
}
|
}
|
|
// 如果不是最后一次尝试,则等待一段时间后重试
|
if (retry < maxRetries - 1)
|
{
|
await UniTask.Delay(1000); // 等待1秒后重试
|
}
|
}
|
catch (OperationCanceledException)
|
{
|
Debug.LogError($"获取远程版本超时,尝试次数: {retry + 1}/{maxRetries}");
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"获取远程版本异常: {e.Message},尝试次数: {retry + 1}/{maxRetries}");
|
}
|
}
|
|
// 所有重试都失败,显示提示窗口
|
ShowVersionFetchFailedDialog();
|
|
// 返回空字符串表示获取失败
|
return string.Empty;
|
}
|
|
/// <summary>
|
/// 显示版本获取失败对话框
|
/// </summary>
|
/// <remarks>
|
/// 这是一个预留接口,需要在实际项目中实现
|
/// </remarks>
|
private static void ShowVersionFetchFailedDialog()
|
{
|
// 这里是预留的接口,用于显示版本获取失败的对话框
|
// 在实际项目中,可以根据需要实现具体的UI显示逻辑
|
Debug.LogError("获取版本信息失败,请检查网络连接后重试");
|
|
// 示例:可以通过事件系统触发UI显示
|
// EventSystem.Trigger("ShowVersionFetchFailedDialog");
|
|
// 或者通过其他方式显示对话框
|
// UIManager.ShowDialog("获取版本信息失败", "请检查网络连接后重试", "确定");
|
}
|
|
/// <summary>
|
/// 检查版本更新
|
/// </summary>
|
/// <param name="versionUrl">远程版本文件URL</param>
|
/// <returns>更新类型</returns>
|
public static async UniTask<UpdateType> CheckVersionUpdateAsync(string versionUrl)
|
{
|
try
|
{
|
// 获取本地版本
|
string localVersion = await GetLocalVersionAsync();
|
Debug.Log($"本地版本: {localVersion}");
|
|
// 获取远程版本
|
string remoteVersion = await GetRemoteVersionAsync(versionUrl);
|
Debug.Log($"远程版本: {remoteVersion}");
|
|
// 比较版本
|
UpdateType updateType = CompareVersions(localVersion, remoteVersion);
|
return updateType;
|
}
|
catch (Exception e)
|
{
|
Debug.LogError($"检查版本更新失败: {e.Message}");
|
return UpdateType.None;
|
}
|
}
|
}
|