Files
plugin-library/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/HotFixStartState.cs

469 lines
18 KiB
C#
Raw Normal View History

2026-01-07 18:20:13 +08:00
using System;
using System.IO;
2026-04-17 14:42:49 +08:00
using System.Linq;
2026-01-07 18:20:13 +08:00
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");
}
2026-03-18 10:49:42 +08:00
2026-03-18 10:29:55 +08:00
bool isInitSuccess = false;
2026-01-07 18:20:13 +08:00
// 初始化资源包
#if EDITOR_SIMULATEMODE
await EDITOR_SIMULATEMODE(package);
await FsmSystem.SetCurState(nameof(ResEditorSimulateState));
#elif HOST_PLAYMODE
//登录
2026-04-12 16:48:41 +08:00
if ((AppConfig.IsLogin))
2026-01-07 18:20:13 +08:00
{
2026-03-18 10:29:55 +08:00
await GetServerVersion();
await HOST_PLAYMODE(package);
isInitSuccess = await HOST_PLAYMODE(packageRawFile);
2026-01-07 18:20:13 +08:00
}
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();
2026-03-18 10:29:55 +08:00
#elif LOCAL_PLAYMODE
await OFFLINE_PLAYMODE(package);
await UpdateLocalPackage(package);
2026-01-07 18:20:13 +08:00
2026-03-18 10:49:42 +08:00
isInitSuccess = await OFFLINE_PLAYMODE(packageRawFile);
2026-03-18 10:29:55 +08:00
if (isInitSuccess)
await UpdateLocalPackage(packageRawFile);
await LoadHotfixSettings();
2026-04-16 22:04:55 +08:00
#elif WEB_NORMAL
2026-04-17 14:11:12 +08:00
if ((AppConfig.IsLogin))
{
await GetServerVersion();
await HOST_PLAYMODE(package);
}
else
{
await OFFLINE_PLAYMODE(package);
await ChChe_PLAYMODE(package);
}
2026-01-07 18:20:13 +08:00
2026-04-17 14:11:12 +08:00
await UpdateLocalPackage(package);
await LoadHotfixSettings();
2026-01-07 18:20:13 +08:00
#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)
{
2026-04-17 14:11:12 +08:00
#if WEB_NORMAL
2026-04-17 14:42:49 +08:00
var initParams = YooAssetFileSystem.WebInitializeParameter(package.PackageName);
2026-04-17 14:11:12 +08:00
#else
2026-01-07 18:20:13 +08:00
var initParams = YooAssetFileSystem.HostInitializeParameter(package.PackageName);
2026-04-17 14:11:12 +08:00
#endif
2026-01-07 18:20:13 +08:00
// initParameters.CacheFileSystemParameters = cacheFileSystemParams;
2026-01-08 12:25:29 +08:00
try
{
var initOperation = package.InitializeAsync(initParams);
2026-01-07 18:20:13 +08:00
2026-01-08 12:25:29 +08:00
await initOperation;
2026-01-07 18:20:13 +08:00
2026-01-08 12:25:29 +08:00
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("UnityEvo:从远程加载资源包,初始化成功!");
2026-04-17 14:42:49 +08:00
#if WEB_NORMAL
string extractPath = Path.Combine(Application.persistentDataPath, "DownloadedContent",package.PackageName);
await CreateResourceImporter(package, extractPath);
#endif
2026-01-08 12:25:29 +08:00
return true;
}
else
{
Debug.LogWarning($"UnityEvo:从远程加载资源包,初始化失败:{initOperation.Error}");
}
2026-01-07 18:20:13 +08:00
}
2026-01-08 12:25:29 +08:00
catch (Exception e)
2026-01-07 18:20:13 +08:00
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:从远程加载资源包,初始化失败:{e}");
2026-01-07 18:20:13 +08:00
}
2026-01-08 12:25:29 +08:00
return false;
2026-01-07 18:20:13 +08:00
}
2026-03-18 10:49:42 +08:00
private async UniTask<bool> OFFLINE_PLAYMODE(ResourcePackage package)
2026-01-07 18:20:13 +08:00
{
2026-03-18 10:29:55 +08:00
var initParams = YooAssetFileSystem.OfflineInitializeParameter();
var initOperation = package.InitializeAsync(initParams);
await initOperation;
2026-03-18 10:49:42 +08:00
if (initOperation.Status == EOperationStatus.Succeed)
Debug.Log("UnityEvo:从本地加载资源包,初始化成功!");
else
{
Debug.LogWarning($"UnityEvo:从本地加载资源包,初始化失败:{initOperation.Error}");
return false;
}
2026-03-18 10:29:55 +08:00
var operation = package.RequestPackageVersionAsync();
await operation;
if (operation.Status == EOperationStatus.Succeed)
{
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION", operation.PackageVersion);
Debug.Log("UnityEvo:从本地加载资源包,初始化获取版本号成功!");
2026-03-18 10:49:42 +08:00
return true;
2026-03-18 10:29:55 +08:00
}
else
{
Debug.LogError($"UnityEvo:从本地加载资源包,初始化获取版本号失败!");
2026-03-18 10:49:42 +08:00
return false;
2026-03-18 10:29:55 +08:00
}
2026-01-07 18:20:13 +08:00
}
2026-03-18 10:29:55 +08:00
2026-01-07 18:20:13 +08:00
private async UniTask<bool> ChChe_PLAYMODE(ResourcePackage package)
{
//Debug.Log("UnityEvo:网络连接不通畅,切换缓存加载!");
var initParams = YooAssetFileSystem.HostInitializeParameter(package.PackageName);
2026-01-08 12:25:29 +08:00
try
2026-01-07 18:20:13 +08:00
{
2026-01-08 12:25:29 +08:00
var initOperation = package.InitializeAsync(initParams);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("UnityEvo:从本地缓存中资源包,初始化成功!");
}
else
{
Debug.LogWarning($"UnityEvo:从本地缓存中资源包,初始化失败:{initOperation.Error}");
return false;
}
2026-01-07 18:20:13 +08:00
}
2026-01-08 12:25:29 +08:00
catch (Exception e)
2026-01-07 18:20:13 +08:00
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:从本地缓存中资源包,初始化失败:{e}");
2026-01-07 18:20:13 +08:00
}
var operation = package.RequestPackageVersionAsync();
await operation;
if (operation.Status == EOperationStatus.Succeed)
{
CustomPlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION", operation.PackageVersion);
Debug.Log("UnityEvo:从本地缓存中加载资源包,初始化获取版本号成功!");
2026-03-16 18:32:46 +08:00
return true;
2026-01-07 18:20:13 +08:00
}
else
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:从本地缓存中加载资源包,初始化获取版本号失败!");
2026-03-16 18:32:46 +08:00
return false;
2026-01-07 18:20:13 +08:00
}
}
#endregion
private void CopyLocalFile(string packageDomainName)
{
#if UNITY_ANDROID
// 将StreamingAssets下指定的package拷贝到目标路径
string sourcePath = Path.Combine(Application.streamingAssetsPath,
YooAssetSettingsData.GetDefaultYooFolderName(), packageDomainName);
2026-04-16 22:04:55 +08:00
string loadPath = Path.Combine(Application.persistentDataPath, "DownloadedContent",
2026-01-07 18:20:13 +08:00
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
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:StreamingAssets下的{packageDomainName}包不存在");
2026-01-07 18:20:13 +08:00
}
#endif
}
2026-03-18 10:29:55 +08:00
private async UniTask GetServerVersion()
2026-01-07 18:20:13 +08:00
{
// 新增平台判断代码
#if UNITY_EDITOR
BuildTarget buildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
AppConfig.Platform = buildTarget.ToString();
#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());
//获取当前版本
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 //版本一致,加载缓存资源
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:当前版本{oldVersion}资源版本一致,自动跳过更新...");
2026-01-07 18:20:13 +08:00
}
}
else
{
2026-03-17 17:40:27 +08:00
Debug.LogWarning($"UnityEvo:获取资源版本失败: 【{resDmainMessageEntity.message}】");
2026-01-07 18:20:13 +08:00
}
}
private async UniTask UpdateLocalPackage(ResourcePackage package)
{
//更新失败
Debug.Log($"UnityEvo:开始加载本地缓存资源...");
// 获取上次成功记录的版本
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);
2026-01-08 12:25:29 +08:00
if (AppConfig.PackageDomainName.Equals("Main") || HybridClREntrance.Global.stage == StageType.Developer)
2026-01-07 18:20:13 +08:00
{
//加载热更配置文件
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为空无法继续执行后续流程请检查");
}
FsmSystem.SetCurState(nameof(HotFixDllState), domainConfig);
}
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);
2026-04-16 22:04:55 +08:00
string loadPath = Path.Combine(Application.persistentDataPath, "DownloadedContent");
2026-01-07 18:20:13 +08:00
//string loadPath = $"{Application.persistentDataPath}/DownloadedContent/{AppConfig.PackageDomainName}";
2026-01-08 12:25:29 +08:00
// if (Directory.Exists(loadPath))
// {
// Directory.Delete(loadPath, true);
// // 等一帧,让系统真正释放句柄
// await UniTask.DelayFrame(1);
// }
2026-04-12 16:48:41 +08:00
if (DomainAssetSystem.ProgressBarPanel == null)
2026-01-07 18:20:13 +08:00
{
2026-04-12 16:48:41 +08:00
DomainAssetSystem.ProgressBarPanel = Object.Instantiate(Resources.Load<GameObject>("ProgressBarPanel"),
2026-01-07 18:20:13 +08:00
Camera.main.transform).GetOrAddComponent<ProgressBarPanel>();
}
await ZipTool.DownloadAndUnzipAsync(fileId, loadPath, DownLoadProgress, UnzipProgress);
}
private void DownLoadProgress(float progress)
{
Debug.Log($"下载进度:{progress:P0}");
2026-04-12 16:48:41 +08:00
DomainAssetSystem.ProgressBarPanel.SetProgressBarValue("下载中", progress);
2026-01-07 18:20:13 +08:00
}
private void UnzipProgress(float progress)
{
Debug.Log($"解压进度:{progress:P0}");
2026-04-12 16:48:41 +08:00
DomainAssetSystem.ProgressBarPanel.SetProgressBarValue("解压中", progress);
2026-01-07 18:20:13 +08:00
}
#endregion
2026-04-17 14:42:49 +08:00
#region
private async UniTask CreateResourceImporter(ResourcePackage package, string extractPath)
{
// 2. 使用 ResourceImporter 导入解压的文件到缓存系统
string[] files = Directory.GetFiles(extractPath, "*", SearchOption.AllDirectories)
.Where(f => !f.EndsWith(".meta"))
.ToArray();
var importerOp = package.CreateResourceImporter(files, 10, 3);
await importerOp;
if (importerOp.Status == EOperationStatus.Succeed)
{
// 导入成功,现在资源在 YooAsset 缓存中,可以通过正常方式加载
Debug.Log($"成功导入 {files.Length} 个文件");
}
}
#endregion
2026-01-07 18:20:13 +08:00
}
}