using System; using System.Linq; using System.Reflection; using Cysharp.Threading.Tasks; using HybridCLR; using SHFrame; using SHFrame.FSM; using YooAsset; namespace HotMain.SHGame.Procedure { public class ProcedureLoadLauncher : ProcedureBase { private static Assembly _launcherAss; protected override void OnEnter(IFsm procedureOwner) { base.OnEnter(procedureOwner); CreatePackageDownloader(procedureOwner).Forget(); } private async UniTask CreatePackageDownloader(IFsm procedureOwner) { // 打包时内置在包体内的资源 直接先使用包体资源,实例化 登录加载界面后,再去检查是否需要下载更新 //加载AOT await LoadMetadataForAOTAssemblies(); //加载GameLauncher dll #if !UNITY_EDITOR _launcherAss = await LoadHotfixDll(ProcedureInitializePackage.RawFilePackageName, "GameLauncher.dll"); #else _launcherAss = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "GameLauncher"); Log.Warning("加载热更dll:GameLauncher.dll"); #endif //切换到更新资源版本 ChangeState(procedureOwner); } public static async UniTask LoadHotfixDll(string packageName, string name) { Log.Warning($"加载热更dll:{name}"); var package = YooAssets.GetPackage(packageName); var handle = package.LoadRawFileAsync(name); await handle.ToUniTask(); var dllBytes = handle.GetRawFileData(); var assembly = Assembly.Load(dllBytes); Log.Warning($"加载热更dll完成:{name}"); return assembly; } /// /// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。 /// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行 /// private async UniTask LoadMetadataForAOTAssemblies() { var package = YooAssets.GetPackage(ProcedureInitializePackage.RawFilePackageName); Log.Debug("加载AOT泛型dll数据"); // 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。 // 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误 var mode = HomologousImageMode.SuperSet; foreach (var aotDllName in ProcedureInitializePackage.AotMetaAssemblyFiles) { var handle = package.LoadRawFileSync(aotDllName); await handle.ToUniTask(); // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码 var err = RuntimeApi.LoadMetadataForAOTAssembly(handle.GetRawFileData(), mode); Log.Debug($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}"); } } } }