Files
plugin-library/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs
stary 52862dedca
All checks were successful
Plugin Library CI / publish (00.BuildOriginality) (push) Successful in 8s
Plugin Library CI / publish (00.StaryEvo) (push) Successful in 9s
Plugin Library CI / publish (00.StaryEvoTools) (push) Successful in 30s
Plugin Library CI / publish (01.HybridCLR) (push) Successful in 5s
Plugin Library CI / publish (02.InformationSave) (push) Successful in 9s
Plugin Library CI / publish (03.YooAsset) (push) Successful in 47s
Plugin Library CI / publish (04.AudioCore) (push) Successful in 3s
Plugin Library CI / publish (05.TableTextConversion) (push) Successful in 4s
Plugin Library CI / publish (10.StoryEditor) (push) Successful in 2s
Plugin Library CI / publish (11.PointCloudTools) (push) Successful in 3s
Plugin Library CI / publish (12.WeixinMinigame) (push) Successful in 59s
Plugin Library CI / publish (06.UIFarme) (push) Successful in 16s
Plugin Library CI / publish (07.RKTools) (push) Successful in 2s
Plugin Library CI / publish (08.UniTask) (push) Successful in 2s
Plugin Library CI / publish (09.CodeChecker) (push) Successful in 16s
Plugin Library CI / publish (10.XNode) (push) Successful in 9s
111
2026-04-19 12:30:02 +08:00

503 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.IO;
using Cysharp.Threading.Tasks;
using Main;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using YooAsset;
using Object = UnityEngine.Object;
namespace Stary.Evo
{
public class HotFixStartState : AbstractFSMIStateAsync
{
public HotFixStartState(IFsmSystemAsync system) : base(system)
{
}
public override async UniTask OnEnterAsync()
{
Debug.Log("UnityEvo:启动开始资源初始化...");
// 初始化资源系统
YooAssets.Initialize();
//初始化资源加载模块
// 增加包存在性检查
var package = YooAssets.TryGetPackage(AppConfig.PackageDomainName);
if (package == null)
{
Debug.LogWarning($"UnityEvo:资源包 {AppConfig.PackageDomainName} 不存在,正在尝试创建...");
package = YooAssets.CreatePackage(AppConfig.PackageDomainName);
}
YooAssets.SetDefaultPackage(package);
var packageRawFile = YooAssets.TryGetPackage($"{AppConfig.PackageDomainName}_RawFile");
if (packageRawFile == null)
{
Debug.LogWarning($"UnityEvo:资源包 {AppConfig.PackageDomainName}_RawFile 不存在,正在尝试创建...");
packageRawFile = YooAssets.CreatePackage($"{AppConfig.PackageDomainName}_RawFile");
}
bool isInitSuccess = false;
// 初始化资源包
#if EDITOR_SIMULATEMODE
await EDITOR_SIMULATEMODE(package);
await FsmSystem.SetCurState(nameof(ResEditorSimulateState));
#elif HOST_PLAYMODE
//登录
if ((AppConfig.IsLogin))
{
await HOST_PLAYMODE(package);
isInitSuccess = await HOST_PLAYMODE(packageRawFile);
}
else
{
await OFFLINE_PLAYMODE(package);
await ChChe_PLAYMODE(package);
await OFFLINE_PLAYMODE(packageRawFile);
isInitSuccess = await ChChe_PLAYMODE(packageRawFile);
}
await UpdateLocalPackage(package);
if (isInitSuccess)
await UpdateLocalPackage(packageRawFile);
await LoadHotfixSettings();
//await FsmSystem.SetCurState(nameof(ResUpdateLocalState));
#elif LOCAL_PLAYMODE
await OFFLINE_PLAYMODE(package);
await UpdateLocalPackage(package);
isInitSuccess = await OFFLINE_PLAYMODE(packageRawFile);
if (isInitSuccess)
await UpdateLocalPackage(packageRawFile);
await LoadHotfixSettings();
#elif WEB_PLAYMODE || WEIXINMINIGAME
await WEB_PLAYMODE(package);
await UpdateLocalPackage(package);
await LoadHotfixSettings();
#endif
}
#region PLAYMODE
private async UniTask EDITOR_SIMULATEMODE(ResourcePackage package)
{
var initParams = YooAssetFileSystem.EditorSimulateInitializeParameter(package.PackageName);
var initialization = package.InitializeAsync(initParams);
await initialization;
if (initialization.Status == EOperationStatus.Succeed)
{
Assert.AreEqual(EOperationStatus.Succeed, initialization.Status);
Debug.Log("UnityEvo:资源包初始化成功!");
}
else
{
Debug.LogError($"UnityEvo:资源包初始化失败:{initialization.Error}");
}
}
private async UniTask<bool> HOST_PLAYMODE(ResourcePackage package)
{
var resDmainResponse = await GetServerDomainVersion();
//获取当前版本
var oldVersion = CustomPlayerPrefs.GetString($"{AppConfig.PackageDomainName}_GAME_VERSION");
//版本不一致,开始下载
if (resDmainResponse.PackageVersion != oldVersion)
{
await Download(resDmainResponse.DocumentFileId);
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION",resDmainResponse.PackageVersion);
}
else //版本一致,加载缓存资源
{
Debug.LogWarning($"UnityEvo:当前版本{oldVersion}资源版本一致,自动跳过更新...");
}
var initParams = YooAssetFileSystem.HostInitializeParameter(package.PackageName);
// initParameters.CacheFileSystemParameters = cacheFileSystemParams;
try
{
var initOperation = package.InitializeAsync(initParams);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("UnityEvo:从远程加载资源包,初始化成功!");
return true;
}
else
{
Debug.LogWarning($"UnityEvo:从远程加载资源包,初始化失败:{initOperation.Error}");
}
}
catch (Exception e)
{
Debug.LogWarning($"UnityEvo:从远程加载资源包,初始化失败:{e}");
}
return false;
}
private async UniTask<bool> WEB_PLAYMODE(ResourcePackage package)
{
var path = await GetServerVersionPath();
string defaultHostServer = $"{AppConfig.IpConfig}/StaticFiles{path}";
var initParams = YooAssetFileSystem.WebInitializeParameter(package.PackageName, defaultHostServer,defaultHostServer);
// initParameters.CacheFileSystemParameters = cacheFileSystemParams;
try
{
var initOperation = package.InitializeAsync(initParams);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("UnityEvo:从Web加载资源包初始化成功");
return true;
}
else
{
Debug.LogWarning($"UnityEvo:从Web加载资源包初始化失败{initOperation.Error}");
}
}
catch (Exception e)
{
Debug.LogWarning($"UnityEvo:从Web加载资源包初始化失败{e}");
}
return false;
}
private async UniTask<bool> OFFLINE_PLAYMODE(ResourcePackage package)
{
var initParams = YooAssetFileSystem.OfflineInitializeParameter();
var initOperation = package.InitializeAsync(initParams);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
Debug.Log("UnityEvo:从本地加载资源包,初始化成功!");
else
{
Debug.LogWarning($"UnityEvo:从本地加载资源包,初始化失败:{initOperation.Error}");
return false;
}
var operation = package.RequestPackageVersionAsync();
await operation;
if (operation.Status == EOperationStatus.Succeed)
{
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION", operation.PackageVersion);
Debug.Log("UnityEvo:从本地加载资源包,初始化获取版本号成功!");
return true;
}
else
{
Debug.LogError($"UnityEvo:从本地加载资源包,初始化获取版本号失败!");
return false;
}
}
private async UniTask<bool> ChChe_PLAYMODE(ResourcePackage package)
{
//Debug.Log("UnityEvo:网络连接不通畅,切换缓存加载!");
var initParams = YooAssetFileSystem.HostInitializeParameter(package.PackageName);
try
{
var initOperation = package.InitializeAsync(initParams);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("UnityEvo:从本地缓存中资源包,初始化成功!");
}
else
{
Debug.LogWarning($"UnityEvo:从本地缓存中资源包,初始化失败:{initOperation.Error}");
return false;
}
}
catch (Exception e)
{
Debug.LogWarning($"UnityEvo:从本地缓存中资源包,初始化失败:{e}");
}
var operation = package.RequestPackageVersionAsync();
await operation;
if (operation.Status == EOperationStatus.Succeed)
{
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION", operation.PackageVersion);
Debug.Log("UnityEvo:从本地缓存中加载资源包,初始化获取版本号成功!");
return true;
}
else
{
Debug.LogWarning($"UnityEvo:从本地缓存中加载资源包,初始化获取版本号失败!");
return false;
}
}
#endregion
private void CopyLocalFile(string packageDomainName)
{
#if UNITY_ANDROID
// 将StreamingAssets下指定的package拷贝到目标路径
string sourcePath = Path.Combine(Application.streamingAssetsPath,
YooAssetSettingsData.GetDefaultYooFolderName(), packageDomainName);
string loadPath = Path.Combine(Application.temporaryCachePath, "DownloadedContent",
packageDomainName);
// 创建目标目录(如果不存在)
if (!Directory.Exists(loadPath))
{
Directory.CreateDirectory(loadPath);
}
else
{
return;
}
// 检查源路径是否存在
if (Directory.Exists(sourcePath))
{
// 拷贝所有文件
string[] files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
// 计算目标文件路径
string relativePath = Path.GetRelativePath(sourcePath, file);
string destFile = Path.Combine(loadPath, relativePath);
// 创建目标子目录(如果不存在)
string destDir = Path.GetDirectoryName(destFile);
if (!Directory.Exists(destDir))
{
Directory.CreateDirectory(destDir);
}
// 拷贝文件
File.Copy(file, destFile, true);
}
Debug.Log($"UnityEvo:成功将StreamingAssets下的{packageDomainName}包拷贝到{loadPath}");
}
else
{
Debug.LogWarning($"UnityEvo:StreamingAssets下的{packageDomainName}包不存在");
}
#endif
}
private async UniTask<ResDmainResponse> GetServerDomainVersion()
{
// 新增平台判断代码
#if UNITY_EDITOR
BuildTarget buildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
AppConfig.Platform = buildTarget.ToString();
#elif UNITY_WEBGL
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
AppConfig.Platform = "WebGL";
}
#else
AppConfig.Platform = Application.platform.ToString();
#endif
Debug.Log($"目标平台标识: {AppConfig.Platform}");
// 请求资源版本
string url = $"{AppConfig.IpConfig}/ResDomain/GetResDomainByDomain";
var resDmainRequst = new ResDmainRequst()
{
ProductName = AppConfig.ProductName,
DomainName = AppConfig.PackageDomainName,
Platform = AppConfig.Platform,
};
//获取服务器版本
var resDmainMessageEntity = await WebRequestSystem.Post(url, JsonConvert.SerializeObject(resDmainRequst));
if (resDmainMessageEntity.code == 200)
{
ResDmainResponse resDmainResponse =
JsonConvert.DeserializeObject<ResDmainResponse>(resDmainMessageEntity.data.ToString());
return resDmainResponse;
}
else
{
Debug.LogWarning($"UnityEvo:获取资源版本失败: 【{resDmainMessageEntity.message}】");
}
return default;
}
private async UniTask<string> GetServerVersionPath()
{
var resDmainResponse = await GetServerDomainVersion();
if (!string.IsNullOrEmpty(resDmainResponse.DocumentFileId))
{
try
{
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION",resDmainResponse.PackageVersion);
string url = $"{AppConfig.IpConfig}/FileLoad/QueryFileById";
var resDmainMessageEntity = await WebRequestSystem.Get(url, resDmainResponse.DocumentFileId);
if (resDmainMessageEntity.code == 200)
{
DocumentFileResponse documentFileResponse =
JsonConvert.DeserializeObject<DocumentFileResponse>(resDmainMessageEntity.data.ToString());
return documentFileResponse.filePath;
}
else
{
Debug.LogWarning($"UnityEvo:获取资源版本失败: 【{resDmainMessageEntity.message}】");
}
}
catch (Exception e)
{
Debug.LogError($"UnityEvo:获取资源版本失败: 【{resDmainResponse.DocumentFileId}】: {e.Message}");
}
}
else
{
Debug.LogError($"UnityEvo:获取资源版本失败: 【{resDmainResponse.DocumentFileId}】");
}
return "";
}
private async UniTask UpdateLocalPackage(ResourcePackage package)
{
// 获取上次成功记录的版本
string packageVersion =
CustomPlayerPrefs.GetString($"{AppConfig.PackageDomainName}_GAME_VERSION", string.Empty);
if (string.IsNullOrEmpty(packageVersion))
{
Debug.Log($"UnityEvo:{package.PackageName}没有找到本地版本记录,需要更新资源!");
return;
}
Debug.Log($"UnityEvo:获取资源版本 Version : 【{packageVersion}】");
// Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status);
// 加载本地缓存的资源清单文件
var updateManifestOp = package.UpdatePackageManifestAsync(packageVersion, 10);
await updateManifestOp;
if (updateManifestOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:更新本地资源清单 updateManifest : 【成功】");
}
else
{
//更新失败
Debug.LogError($"UnityEvo:加载本地资源清单文件失败,需要更新资源!: 【{updateManifestOp.Error}】");
return;
}
Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status);
}
private async UniTask LoadHotfixSettings()
{
//初始化读取资源配置表
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
if (HybridClREntrance.Global.stage == StageType.Developer)
{
//加载热更配置文件
var loadHotfixSettingsOp = package.LoadAssetAsync<DomainConfig>("Config_DomainConfig");
await loadHotfixSettingsOp;
DomainConfig domainConfig = null;
if (loadHotfixSettingsOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:加载热更配置文件 DomainConfig : 【成功】");
domainConfig = loadHotfixSettingsOp.AssetObject as DomainConfig;
}
else
{
Debug.LogError($"UnityEvo:加载热更配置文件 DomainConfig : 【失败】");
}
if (domainConfig == null)
{
Debug.LogError($"UnityEvo:【{package.PackageName}】加载DomainConfig为空无法继续执行后续流程请检查");
}
#if UNITY_WEBGL
await FsmSystem.SetCurState(nameof(ResStartState), domainConfig,domainConfig.className);
#else
FsmSystem.SetCurState(nameof(HotFixDllState), domainConfig);
#endif
}
else if (HybridClREntrance.Global.stage == StageType.Originality)
{
//加载热更配置文件
var loadArtSceneDataOp = package.LoadAssetAsync<ArtSceneData>("Config_ArtSceneData");
await loadArtSceneDataOp;
ArtSceneData artSceneData = null;
if (loadArtSceneDataOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:加载热更配置文件 ArtSceneData : 【成功】");
artSceneData = loadArtSceneDataOp.AssetObject as ArtSceneData;
await FsmSystem.SetCurState(nameof(ResStartState), null);
}
else
{
Debug.LogError($"UnityEvo:加载热更配置文件 ArtSceneData : 【失败】");
}
if (artSceneData == null)
{
Debug.LogError($"UnityEvo:【{package.PackageName}】加载ArtSceneData为空无法继续执行后续流程请检查");
}
}
}
#region
public async UniTask Download(string fileId)
{
// 在任意MonoBehaviour或DomainBase派生类中
//string loadPath = Path.Combine(Application.temporaryCachePath, "DownloadedContent", AppConfig.PackageDomainName);
string loadPath = Path.Combine(Application.temporaryCachePath, "DownloadedContent");
//string loadPath = $"{Application.persistentDataPath}/DownloadedContent/{AppConfig.PackageDomainName}";
// if (Directory.Exists(loadPath))
// {
// Directory.Delete(loadPath, true);
// // 等一帧,让系统真正释放句柄
// await UniTask.DelayFrame(1);
// }
if (DomainAssetSystem.ProgressBarPanel == null)
{
DomainAssetSystem.ProgressBarPanel = Object.Instantiate(Resources.Load<GameObject>("ProgressBarPanel"),
Camera.main.transform).GetOrAddComponent<ProgressBarPanel>();
}
await ZipTool.DownloadAndUnzipAsync(fileId, loadPath, DownLoadProgress, UnzipProgress);
}
private void DownLoadProgress(float progress)
{
Debug.Log($"下载进度:{progress:P0}");
DomainAssetSystem.ProgressBarPanel.SetProgressBarValue("下载中", progress);
}
private void UnzipProgress(float progress)
{
Debug.Log($"解压进度:{progress:P0}");
DomainAssetSystem.ProgressBarPanel.SetProgressBarValue("解压中", progress);
}
#endregion
}
}