Skip to content

优化 GreyMagic 函数调用调度,并统一 native 函数调用 API#91

Open
MnFeN wants to merge 6 commits into
Natsukage:masterfrom
MnFeN:CallScheduler
Open

优化 GreyMagic 函数调用调度,并统一 native 函数调用 API#91
MnFeN wants to merge 6 commits into
Natsukage:masterfrom
MnFeN:CallScheduler

Conversation

@MnFeN
Copy link
Copy Markdown
Collaborator

@MnFeN MnFeN commented May 24, 2026

主要变更

  • 新增 GreyMagicCallScheduler

    Memory.CallInjected64 依赖 GreyMagic 注入的入口函数。调用方会先准备目标函数地址、参数和返回值信息,然后开启一个 FrameLock 窗口,并 hook 入口函数调用指定的函数,直到等到了返回值后才释放入口函数,并将结果返回。

    因此,在直接调用 CallInjected64 时,每次会占用一次 FrameLock 捕获机会,下一次调用需要再次等待游戏线程调用入口函数。目前使用的入口函数为 UI 线程上的函数,意味着每帧只能调用一次。对于短时间内连续发起的多个 native 调用,这会表现为延迟明显累积。

    PR 新增了 GreyMagicCallScheduler,用于在短时间内自动复用同一个 FrameLock 窗口。调度器会将需要执行的 native 调用加入队列,由后台 worker 获取一次 FrameLock 后,在 10 ms 窗口期内连续处理队列中的调用。调用方仍保持同步语义,只等待自己提交的调用完成并接收返回值或异常,不需要等待整个窗口释放。

    这样可以把多个紧邻发生的 CallInjected64 调用合并到同一个 FrameLock 窗口内执行,减少重复等待 hook 入口触发的开销。对于文本指令、目标标记、场地标点等可能连续调用多个游戏内部函数的场景,可以显著降低累计延迟。

    对于连续执行多个开销很小的模组方法,优化非常显著,如 command 指令中连续获取 uiModuleraptureModule 并调用 ProcessChatBox,每 3 帧才能执行一次,而优化后几乎没有速度限制(每帧几十次):

    调整前 调整后

    注:小队聊天等附带发包的指令,自己看到的文本如右图几乎瞬间显示;但发包会进入后台队列,即其他人视角下每 1/30 s 收到一条文本(与使用文本宏一致),相当于 60 fps 下的 2 帧 / 次。目前没有看到因调用函数提速而造成指令被客户端或服务器吞掉的现象(至少当前模块没有)。

  • 新增 PostNamazu 层的 GreyMagic 调用 API

    • 函数调用相关 API:

      • Call(...) / Call<T>(...)
        通过调度器自动复用 FrameLock。

      • DirectCall(...) / DirectCall<T>(...)
        直接调用,不经过调度器。

      • ExecuteInFrameLock(...) / ExecuteInFrameLock<T>(...)
        在调度器 FrameLock 窗口内执行自定义操作。

    • 统一检查空函数指针、空参数、未初始化状态等错误。

    • 统一规范化调用参数,防止 GreyMagic CachedCall 因参数类型不一致导致的报错,且支持 boolenum 等更多类型参数入栈。

    • 对游戏崩溃时 InjectionFinishedEvent was never fired 增加更明确的错误提示。

  • 调整现有模块的 native 调用方式

    • 将现有各模块 native 调用迁移到上述封装。

    • 删除 AssemblyLock 相关的使用:该锁会被 GreyMagic 的 CallInjected64 内部自动调用,用于保护其内部状态,因此原本的这个写法并没有额外锁住什么。

  • 移除 NormalCommand 模组

    • NormalCommand 的回调现在重定向到 Command,以兼容已有调用。

    • 目的是避免继续使用 7.0 后兼容性较差的旧签名,且两个模组目前使用的函数几乎没有区别。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant