【Lua】XLua一键构建工具

将以下代码放入Editor文件夹,点击菜单栏的XLua/一键生成代码和热补丁 即可。

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

/// <summary>
/// XLua自动化构建工具
/// </summary>
public static class XLuaAutoBuild
{
    // 步骤名称与可能方法名的映射表
    private static readonly Dictionary<string, string[]> XLuaMethods = new Dictionary<string, string[]>
    {
        { "清除生成代码", new[] { "ClearGen", "ClearGeneratedCode", "ClearGenerateCode", "ClearGenerate", "ClearAll" } },
        { "生成所有代码", new[] { "GenAll", "GenerateAll", "Generate", "GenerateCode" } },
        { "热补丁注入", new[] { "HotfixInject", "InjectHotfix", "HotfixInjection", "InjectHotfix" } }
    };

    private static bool TryInvokeXLuaMethod(string stepName)
    {
        // 获取所有静态公共方法
        var allMethods = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(a => {
                try { return a.GetTypes(); }
                catch { return Enumerable.Empty<Type>(); }
            })
            .SelectMany(t => {
                try { return t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); }
                catch { return Enumerable.Empty<MethodInfo>(); }
            })
            .Where(m => m.GetParameters().Length == 0)
            .ToList();

        // 获取当前步骤的可能方法名
        if (!XLuaMethods.TryGetValue(stepName, out var possibleMethodNames))
        {
            Debug.LogError($"未配置步骤 '{stepName}' 的方法映射");
            return false;
        }

        // 查找匹配的方法
        var potentialMethods = new List<MethodInfo>();

        foreach (var method in allMethods)
        {
            // 检查方法名是否在可能的方法名列表中
            if (possibleMethodNames.Any(name =>
                method.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
            {
                potentialMethods.Add(method);
            }
        }

        if (potentialMethods.Count == 0)
        {
            Debug.LogError($"未找到匹配 {stepName} 的方法。可能的方法名: {string.Join(", ", possibleMethodNames)}");
            return false;
        }

        // 按类型名排序,优先选择XLua命名空间中的方法
        var orderedMethods = potentialMethods
            .OrderBy(m => m.DeclaringType?.FullName?.Contains("XLua") == true ? 0 : 1)
            .ThenBy(m => m.DeclaringType?.FullName)
            .ToList();

        // 尝试所有可能的方法
        foreach (var method in orderedMethods)
        {
            try
            {
                Debug.Log($"尝试调用: {method.DeclaringType?.FullName}.{method.Name}()");
                method.Invoke(null, null);
                Debug.Log($"{stepName} 成功: {method.DeclaringType?.FullName}.{method.Name}()");
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogWarning($"尝试 {method.Name} 失败: {ex.InnerException?.Message ?? ex.Message}");
            }
        }

        Debug.LogError($"所有匹配方法执行失败: {stepName}");
        return false;
    }

    [MenuItem("XLua/一键生成代码和热补丁", false, 0)]
    public static void AutoGenerateAndInject()
    {
        Debug.Log("开始 XLua 自动化构建流程...");

        bool success = true;

        // 步骤1: 清除旧代码
        success &= ExecuteStep("清除生成代码");

        // 步骤2: 生成新代码
        success &= ExecuteStep("生成所有代码");

        // 步骤3: 热补丁注入
        success &= ExecuteStep("热补丁注入");

        Debug.Log(success
            ? "XLua 构建流程成功完成!"
            : "XLua 构建流程遇到错误!");
    }

    private static bool ExecuteStep(string stepName)
    {
        Debug.Log($"正在执行: {stepName}...");
        bool result = TryInvokeXLuaMethod(stepName);
        Debug.Log(result
            ? $"{stepName}完成"
            : $"{stepName}失败");
        return result;
    }
}