using Assets.Game.Launcher.HotUpdateProxy;
using ET;
using FairyGUI;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace GFGGame.HotUpdate
{
public class HotUpdateEntry
{
public static void Start()
{
Log.Debug("HotUpdateEntry Start 1");
#if !UNITY_EDITOR
LoadMetadataForAOTAssembly();
#endif
Log.Debug("HotUpdateEntry Start 2");
VEngine.Logger.Loggable = false;
//ET
try
{
HotUpdateProxy.Instance.update = Game.Update;
HotUpdateProxy.Instance.lateUpdate = Game.LateUpdate;
HotUpdateProxy.Instance.onApplicationQuit = Game.Close;
Game.EventSystem.Add(HotUpdateCodeLoader.Instance.GetTypes());
Game.EventSystem.Publish(new ET.EventType.AppStart());
}
catch (Exception e)
{
Log.Error(e);
}
Log.Debug("HotUpdateEntry Start 3");
GameController.Start();
Log.Debug("HotUpdateEntry Start 4");
}
///
/// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。
/// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行
///
public static unsafe void LoadMetadataForAOTAssembly()
{
// 可以加载任意aot assembly的对应的dll。但要求dll必须与unity build过程中生成的裁剪后的dll一致,而不能直接使用原始dll。
// 我们在BuildProcessor_xxx里添加了处理代码,这些裁剪后的dll在打包时自动被复制到 {项目目录}/HybridCLRData/AssembliesPostIl2CppStrip/{Target} 目录。
/// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
/// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
///
List aotDllList = new List
{
"mscorlib.dll",
"System.dll",
"System.Core.dll", // 如果使用了Linq,需要这个
"ThirdParty.dll",
"Game.Launcher.dll",
// "Newtonsoft.Json.dll",
// "protobuf-net.dll",
// "Google.Protobuf.dll",
// "MongoDB.Bson.dll",
// "DOTween.Modules.dll",
// "UniTask.dll",
};
foreach (var aotDllName in aotDllList)
{
byte[] dllBytes = GFGAsset.Load($"{LauncherConfig.DllDirAOT}{aotDllName}.bytes").bytes;
fixed (byte* ptr = dllBytes)
{
// 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
int err = HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly((IntPtr)ptr, dllBytes.Length);
Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}");
}
}
}
}
}