Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using XWorld.Framework;
|
||||
|
||||
namespace XGame.MiniGame
|
||||
{
|
||||
// 从代码 AB(manifest.CodeAb)取出 Core/Client 热更 DLL 字节并加载,反射出 IGameClient 入口工厂
|
||||
public sealed class MiniGameAssemblyLoader
|
||||
{
|
||||
public Func<IGameClient> CreateClient { get; private set; }
|
||||
public string Error { get; private set; }
|
||||
|
||||
// localDir: MiniGameDownloader.LocalDir;manifest: 解析好的 game.json
|
||||
public bool Load(string localDir, MiniGameManifest manifest)
|
||||
{
|
||||
string abPath = localDir + manifest.CodeAb;
|
||||
if (!File.Exists(abPath))
|
||||
{ Error = $"缺少代码 AB: {abPath}(需要 codeAb 统一 AB 格式,旧 .bytes 包不再支持)"; return false; }
|
||||
|
||||
AssetBundle ab = null;
|
||||
try
|
||||
{
|
||||
ab = MiniGamePlatform.LoadAssetBundle(abPath);
|
||||
if (ab == null) { Error = "代码 AB 打开失败: " + abPath; return false; }
|
||||
|
||||
byte[] coreBytes = LoadDllBytes(ab, manifest.CoreDll);
|
||||
byte[] clientBytes = LoadDllBytes(ab, manifest.ClientDll);
|
||||
if (coreBytes == null || clientBytes == null)
|
||||
{
|
||||
Error = $"代码 AB 内缺少 {manifest.CoreDll}/{manifest.ClientDll} 的 .bytes(AB 内资产: {string.Join(", ", ab.GetAllAssetNames())})";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Core 先于 Client 加载(Client 依赖 Core)
|
||||
Assembly.Load(coreBytes);
|
||||
Assembly clientAsm = Assembly.Load(clientBytes);
|
||||
|
||||
Type entry = clientAsm.GetType(manifest.ClientEntryType);
|
||||
if (entry == null) { Error = "找不到入口类型 " + manifest.ClientEntryType; return false; }
|
||||
if (!typeof(IGameClient).IsAssignableFrom(entry))
|
||||
{ Error = manifest.ClientEntryType + " 未实现 IGameClient"; return false; }
|
||||
|
||||
CreateClient = () => (IGameClient)Activator.CreateInstance(entry);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Error = "加载小游戏程序集失败: " + e;
|
||||
Debug.LogError("[MiniGameAssemblyLoader] " + Error);
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// DLL 字节已复制进托管内存,AB 本体可卸;false=不销毁已取出的对象
|
||||
if (ab != null) ab.Unload(false);
|
||||
}
|
||||
}
|
||||
|
||||
// "X.dll.bytes" 导入后资产名为 "X.dll"(Unity 剥最后一个扩展名);两种写法都试
|
||||
private static byte[] LoadDllBytes(AssetBundle ab, string dllName)
|
||||
{
|
||||
TextAsset ta = ab.LoadAsset<TextAsset>(dllName) ?? ab.LoadAsset<TextAsset>(dllName + ".bytes");
|
||||
return ta != null ? ta.bytes : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user