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"); } // 初始化资源包 #if EDITOR_SIMULATEMODE await EDITOR_SIMULATEMODE(package); await FsmSystem.SetCurState(nameof(ResEditorSimulateState)); #elif HOST_PLAYMODE bool isInitSuccess = false; //登录 if (((FsmLoadSystem)FsmSystem).IsLogin) { await GetServerVersion(); 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 WEB_PLAYMODE // IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer); // var webServerFileSystemParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(); // var webRemoteFileSystemParams = // FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载 // // var initParameters = new WebPlayModeParameters(); // initParameters.WebServerFileSystemParameters = webServerFileSystemParams; // initParameters.WebRemoteFileSystemParameters = webRemoteFileSystemParams; // // var initOperation = package.InitializeAsync(initParameters); // await initOperation; // // if (initOperation.Status == EOperationStatus.Succeed) // Debug.Log("UnityEvo:资源包初始化成功!"); // else // Debug.LogError($"UnityEvo:资源包初始化失败:{initOperation.Error}"); Debug.LogError($"UnityEvo:暂不支持"); #endif } public override UniTask OnEnterAsync(T param) { return UniTask.CompletedTask; } public override UniTask OnEnterAsync(T1 param1, T2 param2) { return UniTask.CompletedTask; } public override UniTask OnExitAsync() { return UniTask.CompletedTask; } #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 HOST_PLAYMODE(ResourcePackage package) { 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.LogError($"UnityEvo:从远程加载资源包,初始化失败:{e}"); } return false; } private async UniTask OFFLINE_PLAYMODE(ResourcePackage package) { Debug.Log("UnityEvo:网络连接不通畅,切换缓存加载!"); CopyLocalFile(package.PackageName); } private async UniTask 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.LogError($"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.LogError($"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.LogError($"UnityEvo:StreamingAssets下的{packageDomainName}包不存在"); } #endif } private async UniTask GetServerVersion() { // 新增平台判断代码 #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(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 //版本一致,加载缓存资源 { Debug.Log($"UnityEvo:当前版本{oldVersion}资源版本一致,自动跳过更新..."); } } else { Debug.LogError($"UnityEvo:获取资源版本失败: 【{resDmainMessageEntity.message}】"); } } 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); if (AppConfig.PackageDomainName.Equals("Main") || HybridClREntrance.Global.stage == StageType.Developer) { //加载热更配置文件 var loadHotfixSettingsOp = package.LoadAssetAsync("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("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); // } FsmLoadSystem loadSystem = FsmSystem as FsmLoadSystem; if (loadSystem != null && loadSystem.ProgressBarPanel == null) { loadSystem.ProgressBarPanel = Object.Instantiate(Resources.Load("ProgressBarPanel"), Camera.main.transform).GetOrAddComponent(); } await ZipTool.DownloadAndUnzipAsync(fileId, loadPath, DownLoadProgress, UnzipProgress); } private void DownLoadProgress(float progress) { Debug.Log($"下载进度:{progress:P0}"); FsmLoadSystem loadSystem = FsmSystem as FsmLoadSystem; if (loadSystem != null) loadSystem.ProgressBarPanel.SetProgressBarValue("下载中", progress); } private void UnzipProgress(float progress) { Debug.Log($"解压进度:{progress:P0}"); FsmLoadSystem loadSystem = FsmSystem as FsmLoadSystem; if (loadSystem != null) loadSystem.ProgressBarPanel.SetProgressBarValue("解压中", progress); } #endregion } }