跳到主要内容

运行机制

任务类型软件包由助手内置的任务调度器驱动。理解下面几个约定,就能写出正确的任务。

任务入口的三个约定​

任务根目录的 index.lua 需要定义:

名称类型必需说明
CheckTimenumber✅检查间隔,单位毫秒
Check()function✅每次间隔被调用,返回数字决定是否执行 Main
Main()function✅真正执行的逻辑
OnStart()function每次任务开始执行前调用一次
OnStop()function保留字段,当前版本不会自动调用

最小骨架:

apps/黑猫@我的任务/index.lua
-- 每 1000 毫秒检查一次
CheckTime = 1000

-- 返回 0 表示继续等待;返回非 0 表示可以执行 Main
function Check()
return 1
end

function Main()
GoPrint("Main 开始执行")
-- 你的逻辑……
end

完整的执行流程​

当用户启动任务,或任务被 AddTask 调入后,调度器会:

  1. 加载软件包

    • 解析 .hm.json。
    • 把依赖的函数库的 inject/ 脚本注入到游戏客户端。
    • 加载根目录的 index.lua,并配置 require 搜索路径。
    • 注册内置全局函数(Delay、Exit,以及 VM 全局函数)。
  2. 准备本次运行

    • 读取当前任务的配置并写入全局变量 CurrentSettings。
    • 如果定义了 OnStart(),调用一次。
    • 读取全局变量 CheckTime(必须是数字,否则任务报错终止)。
  3. 循环调度

    ┌──────────────────────────────────────────────┐
    │ 每 CheckTime 毫秒调用一次 Check() │
    │ Check() == 0 → 继续等待 │
    │ Check() ~= 0 → 跳出内层循环 │
    └──────────────────────────────────────────────┘
    │
    ▼
    调用一次 Main()
    │
    ▼
    回到上面的循环继续

    也就是说:Check() 是「是否该干活」的轮询,Main() 是「干活」本身。 Main() 返回后会再次进入轮询,不会自动退出任务。

备注

CheckTime 只在每次任务开始时读取一次。运行期间修改它不会生效,需要停止后重新启动任务。

Check 的返回值:是否抢占​

Check() 的返回值有两种含义:

  • 0:条件不满足,继续等待。
  • 非 0:条件满足,执行 Main()。其中:
    • 返回 1:执行 Main() 的同时抢占,即暂停优先级更低的任务;
    • 返回其它非 0 值(如 2):执行 Main(),但不抢占其它任务。

当多个任务同时运行时,任务调度器会根据优先级与抢占状态决定谁在运行。若你只是想让任务 持续工作而不打扰其它任务,返回一个非 1 的非零值即可。

Delay 与 Exit​

两个内置函数控制任务的时间与生命周期:

-- 暂停指定毫秒数(会主动让出执行权)
Delay(500)

-- 立即停止当前任务
Exit()
  • Delay(ms) 在等待期间如果任务被停止,会抛出内部的退出信号,任务随即结束,不会继续往下执行。
  • Exit() 用于在逻辑内部主动结束自己,等同于用户点击「停止」。

CurrentSettings:任务配置​

任务被启动时,助手会把该任务已保存的配置写入全局变量 CurrentSettings(一个 table)。 它来自用户在界面上提交的配置,按「角色 + 任务名」持久化。

function Main()
local settings = CurrentSettings
if settings.fixedPointEnable then
-- 使用了界面上的「定点挂机」复选框
end
end
注意

CurrentSettings 是启动时的快照。在任务运行过程中修改它不会写回存储; 需要持久化时请使用 SetRoleSettings(见 VM 全局函数), 或让用户通过界面重新提交配置。

同名任务与重启​

重复添加一个已经在运行的任务,会先停止旧任务再创建新的,相当于「重启」。 任务停止时,正在 Delay 中的调用会被中断。

下一步:动手写 你的第一个软件包。