# GreenTide Lua API 文档

GreenTide 支持使用 Lua 5.4 脚本进行自动化操作。多个自动化 Lua 脚本会在独立运行态中执行，互不阻塞；打码输入激活时，Lua 的鼠标键盘输出会自动等待打码完成后继续。本文档详细介绍所有可用的 Lua API。

---

## 📋 API 快速总览

### 🎮 统一输入 API（推荐使用）

| 函数 | 功能说明 |
|------|----------|
| `gt.set_input_mode(mode)` | 设置全局输入模式：`auto`/`driver`/`virtual` |
| `gt.get_input_mode()` | 获取当前输入模式 |
| `gt.set_block_mode(mode)` | 设置热键阻断模式：`block`/`passthrough` |
| `gt.get_block_mode()` | 获取当前阻断模式 |
| `gt.key(key, action, driver)` | 统一按键（支持 press/down/up） |
| `gt.click(button, action, driver)` | 统一鼠标点击（支持 click/down/up） |
| `gt.move(x, y, relative, driver)` | 统一鼠标移动（支持绝对/相对） |
| `gt.clear_mouse_moves()` | 清空当前脚本待执行的相对鼠标移动 |
| `gt.get_cursor_shape()` | 获取当前鼠标光标特征码 |
| `gt.start_cursor_shape_monitor(name, interval_ms, released_shape, locked_shape)` | 异步监控鼠标光标特征码 |
| `gt.set_interval(name, interval_ms, callback_name)` | 注册后台定时回调 |
| `gt.clear_interval(name)` | 停止后台定时回调 |
| `gt.start_async_callback(name, interval_ms, callback_code)` | 启动独立 Lua 状态异步回调代码 |
| `gt.scroll(direction, amount)` | 滚轮滚动 |
| `gt.combo(key1, key2, ...)` | 组合键（如 Ctrl+C） |
| `gt.text(text)` | 输入文本 |

### 🔄 多脚本共享变量

| 函数 | 功能说明 |
|------|----------|
| `gt.shared_set(key, value)` | 设置共享变量 |
| `gt.shared_get(key, default)` | 读取共享变量，可提供默认值 |
| `gt.shared_delete(key)` | 删除共享变量 |
| `gt.shared_clear(prefix)` | 按前缀清空共享变量；不传前缀时清空全部 |
| `gt.shared_incr(key, delta)` | 原子递增共享数值 |

### 🖱️ 鼠标操作（旧版 API）

| 函数 | 功能说明 |
|------|----------|
| `gt.mouse_move(x, y)` | 绝对移动鼠标 |
| `gt.mouse_move_relative(dx, dy)` | 相对移动鼠标 |
| `gt.mouse_move_smooth(x, y, duration)` | 平滑移动鼠标 |
| `gt.mouse_get_pos()` | 获取鼠标位置 |
| `gt.mouse_click(button)` | 鼠标点击 |
| `gt.mouse_down(button)` / `gt.mouse_up(button)` | 鼠标按下/释放 |
| `gt.mouse_scroll(direction, amount)` | 滚轮滚动 |

### ⌨️ 键盘操作（旧版 API）

| 函数 | 功能说明 |
|------|----------|
| `gt.key_press(key)` | 按键（按下并释放） |
| `gt.key_down(key)` / `gt.key_up(key)` | 按键按下/释放 |
| `gt.key_combo(key1, key2, ...)` | 组合键 |
| `gt.type_text(text)` | 输入文本（支持中文） |

### 🔧 驱动级操作

| 函数 | 功能说明 |
|------|----------|
| `gt.driver_enabled()` | 检查驱动级是否启用 |
| `gt.get_driver_type()` | 获取当前驱动后端：`nc`/`kminput`/`logitech`/`dd` |
| `gt.set_driver_type(type)` | 切换当前驱动后端，返回是否成功和当前后端 |
| `gt.driver_key_press(key)` | 驱动级按键 |
| `gt.driver_key_down(key)` / `gt.driver_key_up(key)` | 驱动级按键按下/释放 |
| `gt.driver_mouse_move(x, y)` | 驱动级绝对移动 |
| `gt.driver_mouse_move_relative(dx, dy)` | 驱动级相对移动 |
| `gt.driver_mouse_click(button)` | 驱动级鼠标点击 |

### 🎮 虚拟手柄 API

| 函数 | 功能说明 |
|------|----------|
| `gt.gamepad_available()` | 检查虚拟手柄是否可用 |
| `gt.gamepad_button(button_name, action)` | 发送虚拟手柄按键 down/up |
| `gt.gamepad_press(button_name, hold_ms)` | 虚拟手柄按下并释放 |
| `gt.gamepad_reset()` | 重置虚拟手柄所有按键状态 |

### ⏱️ 延时函数

| 函数 | 功能说明 |
|------|----------|
| `gt.sleep(ms)` | 延时指定毫秒（支持小数） |
| `gt.sleep_random(min, max)` | 随机延时 |
| `gt.loop(count, interval, callback)` | 循环调用脚本函数；`count=0` 表示直到脚本被停止 |

### 🎯 热键绑定

| 函数 | 功能说明 |
|------|----------|
| `gt.bind_hotkey(hotkey, callback)` | 绑定热键（单次执行） |
| `gt.bind_hotkey_loop(hotkey, callback, interval)` | 绑定热键循环（Toggle 模式） |
| `gt.toggle_hotkey_loop(hotkey)` | 切换热键循环状态 |
| `gt.stop_hotkey_loop(hotkey)` | 停止指定热键循环 |
| `gt.stop_all_loops()` | 停止所有循环 |
| `gt.is_loop_running(hotkey)` | 检查循环是否运行中 |
| `gt.unbind_hotkey(hotkey)` | 解除热键绑定 |
| `gt.is_key_pressed(key)` | 检查按键是否按下 |

### 🎮 进程限制热键

| 函数 | 功能说明 |
|------|----------|
| `gt.set_hotkey_process(hotkey, ...)` | 设置热键只在指定进程生效 |
| `gt.clear_hotkey_process(hotkey)` | 清除热键进程限制 |
| `gt.get_hotkey_process(hotkey)` | 获取热键进程限制列表 |
| `gt.get_foreground_process()` | 获取当前前台进程名 |
| `gt.get_foreground_window_rect()` | 获取当前前台窗口位置和大小 |
| `gt.highlight_rect(x, y, width, height, duration, color, is_physical)` | 显示屏幕高亮框 |
| `gt.hide_highlight()` | 隐藏屏幕高亮框 |

### 📦 宏调用

| 函数 | 功能说明 |
|------|----------|
| `gt.run_macro(hotkey)` | 运行 GUI 绑定的宏 |
| `gt.stop_macro(hotkey)` | 停止宏执行 |
| `gt.list_macros()` | 列出所有可用宏 |
| `gt.has_macro(hotkey)` | 检查宏是否存在 |
| `gt.get_macro_info(hotkey)` | 获取宏详细信息 |

### 📚 宏库 API

| 函数 | 功能说明 |
|------|----------|
| `gt.run_macro_by_name(name)` | 按名称运行宏库中的宏 |
| `gt.stop_macro_by_name(name)` | 停止宏库中的宏 |
| `gt.list_macro_library()` | 列出宏库中所有宏 |
| `gt.has_macro_by_name(name)` | 检查宏库中宏是否存在 |
| `gt.list_device_bindings(kind)` | 列出当前设备动作 |
| `gt.has_device_binding(kind, target)` | 检查指定设备动作是否存在 |
| `gt.run_device_binding(kind, target)` | 立即执行当前设备动作 |
| `gt.get_macro_library_info(name)` | 获取宏库宏详细信息 |

### 🎨 取色识别

| 函数 | 功能说明 |
|------|----------|
| `gt.get_pixel_color(x, y)` | 获取指定坐标像素颜色 |
| `gt.check_color(x, y, r, g, b, tolerance)` | 检查颜色是否匹配 |
| `gt.check_colors(points)` | 检查多个颜色点是否全部匹配 |
| `gt.find_color(x, y, w, h, r, g, b, tolerance, step)` | 在区域内查找颜色，返回匹配坐标 |
| `gt.find_color_region(region, r, g, b, tolerance, step)` | 使用 `{x,y,width,height}` 区域表查找颜色 |
| `gt.check_saved_colors(name)` | 按视觉识别里的取色配置名检测保存的取色模板 |

### 📸 截图功能

| 函数 | 功能说明 |
|------|----------|
| `gt.screenshot(x, y, w, h, filename)` | 截图保存为 PNG 文件 |
| `gt.screenshot_base64(x, y, w, h)` | 截图返回 Base64 编码 |

### 🖼️ 图像识别

| 函数 | 功能说明 |
|------|----------|
| `gt.find_image(template, region)` | 在屏幕上搜索图像 |
| `gt.image_match(template, x, y, w, h, threshold)` | 指定区域图像匹配 |
| `gt.find_saved_image(name, region)` | 按视觉识别里的识图配置名查找保存的识图模板 |

### 🛠️ 系统状态

| 函数 | 功能说明 |
|------|----------|
| `gt.is_captcha_input_active()` | 检查打码输入是否正在独占键鼠 |

---

## 自动流程与 Lua 触发规则

- 自动流程编排和 Lua 脚本属于会员功能。免费模式可以看到入口和已有配置，但不能新建、保存、启用或运行。
- Lua 脚本按“每个脚本自己的快捷键”触发。启用的脚本只有在绑定快捷键被按下时才执行，不再通过宏开关总开关触发。
- 脚本快捷键会和普通映射、宏、预设、流程快捷键做冲突检查，冲突时保存失败。
- `gt.find_saved_image` 和 `gt.check_saved_colors` 按配置名调用视觉识别页保存的模板，不需要在 Lua 里加载本地图片。
- `gt.find_image`、`gt.image_match`、`gt.get_pixel_color`、`gt.check_color`、`gt.check_colors`、`gt.find_color` 和 `gt.find_color_region` 复用视觉识别/取色能力。
- 打码输入激活时，Lua 鼠标键盘输出会自动等待；需要主动避让时可用 `gt.is_captcha_input_active()` 查询当前状态。

## 常用示例

### 多点取色

```lua
local ok = gt.check_colors({
  { x = 100, y = 200, r = 255, g = 80, b = 40, tolerance = 12 },
  { x = 120, y = 200, r = 250, g = 76, b = 38, tolerance = 12 },
})

if ok then
  gt.key("f", "press")
end
```

### 调用取色模板

```lua
if gt.check_saved_colors("技能可用") then
  gt.key("1", "press")
  gt.log("技能可用，已按 1")
end
```

### 区域查找颜色

```lua
local x, y = gt.find_color(800, 400, 360, 260, 255, 210, 80, 16, 3)
if x and y then
  gt.move(x, y, false)
  gt.click("left", "click")
end
```

### 区域找图

```lua
local x, y, score = gt.find_saved_image("确认按钮", {
  x = 600,
  y = 300,
  width = 800,
  height = 500,
})

if x and score >= 0.8 then
  gt.move(x, y, false)
  gt.click("left", "click")
end
```

### 全屏找图

```lua
local x, y, score = gt.find_saved_image("开始按钮")
if x then
  gt.mouse_move(x, y)
  gt.mouse_click("left")
end
```

### 循环执行按键、鼠标、找图、找色

```lua
function tick()
  local colorX, colorY = gt.find_color_region({ x = 900, y = 500, width = 240, height = 160 }, 255, 64, 64, 18, 4)
  if colorX then
    gt.move(colorX, colorY, false)
    gt.click("left", "click")
    return
  end

  local imageX, imageY = gt.find_saved_image("目标图标")
  if imageX then
    gt.mouse_move_smooth(imageX, imageY, 120)
    gt.key_press("space")
    return
  end

  gt.key("tab", "press")
  gt.move(8, 0, true)
end

gt.loop(0, 80, "tick")
```

### 🛠️ 系统函数

| 函数 | 功能说明 |
|------|----------|
| `gt.get_screen_size()` | 获取屏幕分辨率 |
| `gt.get_active_window()` | 获取当前活动窗口标题 |
| `gt.get_foreground_window_rect()` | 获取当前前台窗口位置和大小 |
| `gt.highlight_rect(x, y, width, height, duration, color, is_physical)` | 显示屏幕高亮框 |
| `gt.hide_highlight()` | 隐藏屏幕高亮框 |
| `gt.log(message)` | 输出日志 |
| `gt.debug(message)` | 输出调试日志 |
| `gt.reminder(text, duration)` | 显示 GUI 提醒通知 |
| `gt.schedule_reminder(text, delay, duration)` | 设置定时提醒 |
| `gt.speak(text, voice)` | 立即播报文本 |
| `gt.set_voice(voice)` | 设置默认语音 |
| `gt.get_voice()` | 获取当前默认语音 |
| `gt.list_voices()` | 列出可用语音 |
| `gt.get_global_settings()` | 获取当前全局设置快照 |
| `gt.update_global_settings(patch)` | 更新全局设置并立即生效 |
| `gt.get_trigger_key()` | 获取全局宏开关键 |
| `gt.set_trigger_key(key)` | 设置或清除全局宏开关键 |
| `gt.msgbox(title, message)` | 显示消息框 |
| `gt.get_time()` | 获取当前时间戳（毫秒） |
| `gt.set_apex_config(sens, zoom)` | 设置 Apex 灵敏度配置 |
| `gt.get_apex_modifier()` | 获取 Apex 灵敏度修正系数 |

### 🔒 鼠标锁定位置 API

| 函数 | 功能说明 |
|------|----------|
| `gt.set_lock_offset(x, y)` | 设置鼠标锁定位置偏移（相对于屏幕中心） |
| `gt.get_lock_offset()` | 获取当前鼠标锁定位置偏移 |
| `gt.reset_lock_offset()` | 重置鼠标锁定位置偏移为 (0, 0) |
| `gt.set_override(config)` | 设置 Lua 覆盖态（偏移、跳过居中、跳过右键锁定） |
| `gt.reset_override()` | 重置 Lua 覆盖态 |

### 🎮 主控热键 API

| 函数 | 功能说明 |
|------|----------|
| `gt.register_hotkey(hotkey)` | 注册主控热键 |
| `gt.enable_hotkey_right_click(enabled)` | 设置热键按下时是否执行右键 |
| `gt.is_hotkey_right_click_enabled()` | 获取热键右键开关状态 |
| `gt.toggle_scripts()` | 切换脚本开关状态 |
| `gt.enable_scripts()` | 启用脚本 |
| `gt.disable_scripts()` | 禁用脚本 |
| `gt.is_scripts_enabled()` | 检查脚本是否启用 |

### 🖱️ 右键锁定 API

| 函数 | 功能说明 |
|------|----------|
| `gt.lock_right_click()` | 锁定右键 |
| `gt.unlock_right_click()` | 解锁右键 |
| `gt.is_right_click_locked()` | 获取右键锁定状态 |

### ⚙️ 开关控制 API

| 函数 | 功能说明 |
|------|----------|
| `gt.enable_wasd_switch(enabled)` | 开启/关闭 WASD 开关 |
| `gt.is_wasd_switch_enabled()` | 获取 WASD 开关状态 |
| `gt.enable_driver_key(enabled)` | 开启/关闭驱动级按键 |
| `gt.is_driver_key_enabled()` | 获取驱动级按键状态 |

### 🎮 手柄控制 API

| 函数 | 功能说明 |
|------|----------|
| `gt.get_gamepad_status()` | 获取手柄状态 |
| `gt.set_gamepad_vibration(enabled, intensity)` | 设置手柄震动 |
| `gt.set_gamepad_deadzone(deadzone, index)` | 设置手柄死区 |

### 🖼️ 图像识别控制 API

| 函数 | 功能说明 |
|------|----------|
| `gt.start_image_recognition(config_ids)` | 启动图像识别 |
| `gt.stop_image_recognition()` | 停止图像识别 |
| `gt.get_image_recognition_status()` | 获取图像识别状态 |

### 🎨 颜色识别控制 API

| 函数 | 功能说明 |
|------|----------|
| `gt.pick_color(x, y)` | 获取指定坐标颜色（返回 r, g, b, hex） |
| `gt.find_color(x, y, w, h, r, g, b, tolerance, step)` | 在区域内查找颜色，返回匹配坐标 |
| `gt.find_color_region(region, r, g, b, tolerance, step)` | 使用区域表查找颜色 |
| `gt.get_color_recognition_status()` | 获取取色识别状态 |

### 🖥️ 屏幕与进程 API

| 函数 | 功能说明 |
|------|----------|
| `gt.get_screen_dpi()` | 获取屏幕 DPI（返回 scale, scalePercent） |
| `gt.set_excluded_processes(processes)` | 设置排除进程列表 |
| `gt.get_excluded_processes()` | 获取排除进程列表 |

### 🎬 录制功能 API

| 函数 | 功能说明 |
|------|----------|
| `gt.start_recording(use_real_delay, default_delay)` | 开始录制 |
| `gt.stop_recording()` | 停止录制并返回动作序列 |
| `gt.get_recording_status()` | 获取录制状态 |
| `gt.clear_recording()` | 清空录制 |
| `gt.list_timer_tasks()` | 列出定时任务中心里的任务 |
| `gt.save_timer_task(task)` | 创建或更新定时任务 |
| `gt.delete_timer_task(task_id)` | 删除定时任务 |
| `gt.execute_timer_task(task_id)` | 立即执行定时任务 |

### 📝 动作注册 API

| 函数 | 功能说明 |
|------|----------|
| `gt.register_hotkey_actions(hotkey, actions, execution_mode, loop_count, loop_duration_seconds, random_delay_enabled, random_delay_min, random_delay_max)` | 注册热键动作序列 |
| `gt.unregister_hotkey_script(hotkey)` | 注销热键脚本 |
| `gt.set_mouse_skill_interval(button, interval)` | 设置鼠标技能循环间隔 |

### 🎯 准星覆盖层 API

| 函数 | 功能说明 |
|------|----------|
| `gt.crosshair_show()` | 显示准星 |
| `gt.crosshair_hide()` | 隐藏准星 |
| `gt.crosshair_toggle()` | 切换准星显示状态 |
| `gt.crosshair_config(type, color, size, thickness)` | 设置准星配置 |
| `gt.crosshair_get_config()` | 获取准星配置 |
| `gt.crosshair_type(type)` | 设置准星类型（dot/cross/cross-gap/circle） |
| `gt.crosshair_color(color)` | 设置准星颜色（如 "#ff0000"） |
| `gt.crosshair_size(size)` | 设置准星大小（1-200） |
| `gt.crosshair_offset(x, y)` | 设置准星位置偏移 |
| `gt.crosshair_fixed(enabled)` | 设置准星固定模式 |

---



## 快速开始

### 基本示例（使用统一 API）

```lua
-- 设置输入模式（可选）
gt.set_input_mode("auto")  -- auto/driver/virtual

-- 移动鼠标到屏幕中央并点击
local w, h = gt.get_screen_size()
gt.move(w / 2, h / 2)       -- 统一移动函数
gt.sleep(100)
gt.click("left")            -- 统一点击函数

-- 按键
gt.key("a")                 -- 按下并释放 A
gt.key("space", "down")     -- 按下空格
gt.key("space", "up")       -- 释放空格

-- 组合键
gt.combo("ctrl", "c")       -- Ctrl+C

-- 输出日志
gt.log("操作完成！")
```

### 虚拟/驱动级切换示例

```lua
-- 方式1：全局设置输入模式
gt.set_input_mode("driver")  -- 全部使用驱动级
gt.key("a")                  -- 使用驱动级
gt.click("left")             -- 使用驱动级

gt.set_input_mode("virtual") -- 全部使用虚拟
gt.key("a")                  -- 使用虚拟
gt.click("left")             -- 使用虚拟

-- 方式2：单个函数指定
gt.set_input_mode("auto")    -- 恢复自动
gt.key("a", "press", true)   -- 强制使用驱动级
gt.key("b", "press", false)  -- 强制使用虚拟
gt.click("left", "click", true)   -- 驱动级点击
gt.move(100, 200, false, true)    -- 驱动级移动
```

### 热键阻断模式示例

```lua
-- 阻断模式（默认）：按热键只执行脚本，原始按键被拦截
gt.set_block_mode("block")
function send_abc()
    gt.key("a")
    gt.key("b")
    gt.key("c")
end
gt.bind_hotkey("f1", "send_abc")
-- 按 F1：只发送 a、b、c，F1 本身不传递

-- Passthrough 模式：原始按键也传递
gt.set_block_mode("passthrough")
function send_23()
    gt.key("2")
    gt.key("3")
end
gt.bind_hotkey("1", "send_23")
-- 按 1：先传递原始的 1，然后脚本发送 2、3，最终效果是 1、2、3
```

### 循环宏示例

```lua
-- 简单的自动连点器
function auto_clicker()
    while gt.is_key_pressed("F1") do
        gt.click("left")
        gt.sleep_random(50, 100)
    end
end
```

### 调用 GUI 录制的宏

```lua
-- 列出所有可用的宏
local macros = gt.list_macros()
for _, hotkey in ipairs(macros) do
    gt.log("可用宏: " .. hotkey)
end

-- 运行 GUI 上绑定到 F2 的宏
if gt.has_macro("f2") then
    gt.run_macro("f2")
end

-- 获取宏信息
local info = gt.get_macro_info("mouse_left")
if info then
    gt.log("鼠标左键宏有 " .. info.action_count .. " 个动作")
end
```


## 统一输入 API（推荐）

统一 API 使用相同的函数名处理虚拟和驱动级输入，通过参数或全局设置来切换。

### gt.set_input_mode(mode)

设置全局输入模式。

**参数：**
- `mode` (string): 输入模式
  - `"auto"`: 自动模式（如果驱动可用则使用驱动，否则使用虚拟）
  - `"driver"`: 强制使用驱动级（需要驱动可用）
  - `"virtual"`: 强制使用虚拟输入

**返回值：** 无

**示例：**
```lua
gt.set_input_mode("driver")   -- 强制驱动级
gt.set_input_mode("virtual")  -- 强制虚拟
gt.set_input_mode("auto")     -- 自动选择（默认）
```

---

### gt.set_block_mode(mode)

设置热键阻断模式（是否阻止原始按键传递）。

**参数：**
- `mode` (string): 阻断模式
  - `"block"` 或 `"global"`：阻断原始按键，只执行脚本（默认）
  - `"passthrough"` 或 `"pass"`：不阻断，原始按键也会传递

**返回值：** 无

**示例：**
```lua
-- 默认模式：按 F1 触发脚本，F1 本身不传递
gt.set_block_mode("block")

-- passthrough 模式：按 1 触发脚本发送 2、3，最终效果是 1、2、3 都发送
gt.set_block_mode("passthrough")

-- 示例：按 1 发送 2 和 3
gt.set_block_mode("passthrough")
function send_combo()
    gt.key("2")
    gt.sleep(50)
    gt.key("3")
end
gt.bind_hotkey("1", "send_combo")
-- 按 1 时：原始的 1 也会传递，加上脚本发送的 2、3，最终是 1、2、3
```

---

### gt.get_block_mode()

获取当前热键阻断模式。

**返回值：**
- `mode` (string): 当前阻断模式（"block" 或 "passthrough"）

**示例：**
```lua
local mode = gt.get_block_mode()
gt.log("当前阻断模式: " .. mode)
```

---

### gt.get_input_mode()

获取当前输入模式。

**返回值：**
- `mode` (string): 当前输入模式

**示例：**
```lua
local mode = gt.get_input_mode()
gt.log("当前模式: " .. mode)
```

---

### gt.key(key, action, driver)

统一按键函数，支持虚拟和驱动级。

**参数：**
- `key` (string): 按键名称
- `action` (string, 可选): 操作类型
  - `"press"`: 按下并释放（默认）
  - `"down"`: 仅按下
  - `"up"`: 仅释放
- `driver` (boolean, 可选): 是否使用驱动级
  - `nil`: 使用全局设置
  - `true`: 强制驱动级
  - `false`: 强制虚拟

**返回值：** 无

**示例：**
```lua
-- 基本用法
gt.key("a")              -- 按 A（使用全局模式）
gt.key("space")          -- 按空格
gt.key("f1")             -- 按 F1

-- 指定动作
gt.key("shift", "down")  -- 按下 Shift
gt.key("a")              -- 按 A
gt.key("shift", "up")    -- 释放 Shift

-- 指定输入方式
gt.key("a", "press", true)   -- 驱动级按 A
gt.key("a", "press", false)  -- 虚拟按 A
```

---

### gt.click(button, action, driver)

统一鼠标点击函数，支持虚拟和驱动级。

**参数：**
- `button` (string): 鼠标按钮
  - `"left"` 或 `"lbutton"`: 左键（默认）
  - `"right"` 或 `"rbutton"`: 右键
  - `"middle"` 或 `"mbutton"`: 中键
  - `"x1"` 或 `"xbutton1"`: 侧键1
  - `"x2"` 或 `"xbutton2"`: 侧键2
- `action` (string, 可选): 操作类型
  - `"click"`: 点击（默认）
  - `"down"`: 仅按下
  - `"up"`: 仅释放
- `driver` (boolean, 可选): 是否使用驱动级

**返回值：** 无

**示例：**
```lua
-- 基本用法
gt.click("left")         -- 左键点击
gt.click("right")        -- 右键点击
gt.click("middle")       -- 中键点击

-- 拖拽操作
gt.click("left", "down") -- 按下左键
gt.move(100, 100, true)  -- 相对移动
gt.click("left", "up")   -- 释放左键

-- 指定输入方式
gt.click("left", "click", true)   -- 驱动级左键点击
gt.click("right", "click", false) -- 虚拟右键点击
```

---

### gt.move(x, y, relative, driver)

统一鼠标移动函数，支持虚拟和驱动级。

**参数：**
- `x` (number): X 坐标或偏移
- `y` (number): Y 坐标或偏移
- `relative` (boolean, 可选): 是否相对移动
  - `false`: 绝对坐标（默认）
  - `true`: 相对偏移
- `driver` (boolean, 可选): 是否使用驱动级

**返回值：** 无

**示例：**
```lua
-- 绝对移动
gt.move(500, 300)              -- 移动到 (500, 300)
gt.move(500, 300, false)       -- 同上，显式指定绝对移动

-- 相对移动
gt.move(10, 20, true)          -- 相对当前位置移动 (10, 20)
gt.move(-5, 0, true)           -- 向左移动 5 像素

-- 指定输入方式
gt.move(100, 200, false, true)  -- 驱动级绝对移动
gt.move(10, 20, true, true)     -- 驱动级相对移动
gt.move(100, 200, false, false) -- 虚拟绝对移动
```

---

### gt.clear_mouse_moves()

清空当前 Lua 脚本待执行的相对鼠标移动。适合识图命中后停止搜索转镜头，避免命中前已经排队的相对移动继续执行；如果当前脚本正保持左键按下，会按队列顺序短暂重置左键 up/down，帮助游戏退出拖动镜头状态。

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
local x, y, score = gt.find_saved_image(image)
if x and score >= 0.8 then
    gt.clear_mouse_moves()
end
```

---

### gt.get_cursor_shape()

获取当前 Windows 鼠标光标特征码。通常返回 `0` 表示没有可用的可见光标特征；非 `0` 表示当前光标形状可被识别，可用于脚本判断游戏内鼠标状态变化。

**返回值：**
- `shape` (number): 当前鼠标光标特征码

**示例：**
```lua
local shape = gt.get_cursor_shape()
gt.log("鼠标特征码: " .. tostring(shape))
```

---

### gt.start_cursor_shape_monitor(name, interval_ms, released_shape, locked_shape)

在 Go 后台异步监控当前鼠标光标特征码，不阻塞当前 Lua 主循环。默认可用 `released_shape=0` 判断释放状态，`locked_shape=25200` 判断锁定状态；其他值会记录为 `other`。

监控结果会写入共享变量：
- `cursor_shape_monitor:<name>:state`：`released` / `locked` / `other`
- `cursor_shape_monitor:<name>:shape`：当前特征码
- `cursor_shape_monitor:<name>:running`：是否运行

**返回值：**
- `success` (boolean): 是否启动成功
- `error` (string|nil): 错误信息

**示例：**
```lua
gt.start_cursor_shape_monitor("fight_mouse", 100, 0, 25200)
local state = gt.shared_get("cursor_shape_monitor:fight_mouse:state", "")
local shape = gt.shared_get("cursor_shape_monitor:fight_mouse:shape", -1)
gt.log("鼠标状态: " .. tostring(state) .. " shape=" .. tostring(shape))
```

---

### gt.stop_cursor_shape_monitor(name)

停止指定的鼠标光标特征码异步监控。

**返回值：**
- `stopped` (boolean): 是否停止了正在运行的监控

---

### gt.get_cursor_shape_monitor(name)

读取鼠标光标特征码异步监控状态。

**返回值：**
- `state` (string|nil): `released` / `locked` / `other`
- `shape` (number|nil): 当前特征码
- `updated_at` (number|nil): 最近更新时间戳
- `changed_at` (number|nil): 最近状态变化时间戳
- `running` (boolean): 是否运行

---

### gt.start_async_callback(name, interval_ms, callback_code)

启动一个独立 Lua 状态中的异步回调代码块，启动后先执行一次，之后每隔 `interval_ms` 毫秒执行一次，不阻塞当前 Lua 主循环。适合后台检测并通过 `gt.shared_set()` 写共享状态。

注意：`callback_code` 是 Lua 代码字符串，不是当前脚本里的函数名。它运行在独立 Lua 状态中，因此不能直接访问当前脚本的 local 变量；需要用 `gt.shared_set()` / `gt.shared_get()` 交换数据。

**返回值：**
- `success` (boolean): 是否启动成功
- `error` (string|nil): 错误信息

**示例：**
```lua
gt.start_async_callback("cursor_watch", 100, [[
  local shape = gt.get_cursor_shape()
  gt.shared_set("cursor_watch:shape", shape)
  if shape == 0 then
    gt.shared_set("cursor_watch:state", "released")
  elseif shape == 25200 then
    gt.shared_set("cursor_watch:state", "locked")
  else
    gt.shared_set("cursor_watch:state", "other")
    gt.log("其他鼠标状态 shape=" .. tostring(shape))
  end
]])
```

---

### gt.set_interval(name, interval_ms, callback_name)

注册一个按固定间隔执行的后台回调。适合做独立定时按键、轮询状态、定时触发设备动作。

**参数：**
- `name` (string): 定时器名称。同名会自动替换旧定时器。
- `interval_ms` (number): 执行间隔（毫秒）。
- `callback_name` (string): Lua 函数名。

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**说明：**
- 定时器运行在独立 worker 中，不阻塞当前脚本主循环。
- 回调建议只依赖 `gt` 和 `gt.shared_*` 共享状态；如果依赖局部变量/闭包，不保证一致。

**示例：**
```lua
function press_g()
  gt.key("g", "press", true)
end

local ok, err = gt.set_interval("periodic_g", 3000, "press_g")
if not ok then
  gt.log("注册定时器失败: " .. tostring(err))
end
```

### gt.clear_interval(name)

停止指定名称的后台定时回调。

**返回值：**
- `stopped` (boolean): 是否停止成功

**示例：**
```lua
gt.clear_interval("periodic_g")
```

**完整示例：**
```lua
function periodic_loot()
  gt.key("g", "press", true)
end

gt.set_interval("auto_loot", 3000, "periodic_loot")
gt.log("自动拾取已启动，每 3 秒按一次 G")

function stop_loot()
  gt.clear_interval("auto_loot")
  gt.log("自动拾取已停止")
end

gt.bind_hotkey("f9", "stop_loot")
```

---

### gt.stop_async_callback(name)

停止指定的异步回调代码块。

**返回值：**
- `stopped` (boolean): 是否停止了正在运行的异步回调

---

### gt.get_async_callback_status(name)

读取指定异步回调代码块状态。

**返回值：**
- `running` (boolean): 是否运行
- `ticks` (number): 已执行次数
- `last_error` (string): 最近一次错误
- `updated_at` (number|nil): 最近更新时间戳

---

### gt.scroll(direction, amount, driver)

统一滚轮函数。

**参数：**
- `direction` (string): 滚动方向
  - `"up"`: 向上滚动
  - `"down"`: 向下滚动
- `amount` (number, 可选): 滚动量，默认 120（一个滚动单位）
- `driver` (boolean, 可选): 预留参数（滚轮暂无驱动级支持）

**返回值：** 无

**示例：**
```lua
gt.scroll("up")          -- 向上滚动
gt.scroll("down")        -- 向下滚动
gt.scroll("up", 360)     -- 向上滚动 3 个单位
```

---

### gt.combo(key1, key2, ...)

统一组合键函数，自动使用当前输入模式。

**参数：**
- `key1, key2, ...` (string): 多个按键名称

**返回值：** 无

**示例：**
```lua
gt.combo("ctrl", "c")           -- Ctrl+C
gt.combo("ctrl", "shift", "s")  -- Ctrl+Shift+S
gt.combo("alt", "f4")           -- Alt+F4
gt.combo("ctrl", "alt", "del")  -- Ctrl+Alt+Delete
```

---

### gt.text(text)

输入文本（等同于 gt.type_text）。

**参数：**
- `text` (string): 要输入的文本

**返回值：** 无

**示例：**
```lua
gt.text("Hello World")
gt.text("你好世界")
```

---

### gt.shared_set(key, value)

设置多脚本共享变量。适合把多个独立 Lua 脚本拆开运行后共享状态，例如目标锁定、丢失时间、当前搜索方向。

**参数：**
- `key` (string): 共享变量名
- `value` (boolean/number/string/table/nil): 共享值；传 `nil` 等同删除

**返回值：** `true`/`false`

**示例：**
```lua
gt.shared_set("target_locked", true)
gt.shared_set("lost_since", gt.get_time())
```

---

### gt.shared_get(key, default)

读取共享变量。

**参数：**
- `key` (string): 共享变量名
- `default` (可选): 不存在时返回的默认值

**返回值：** 共享值或默认值

**示例：**
```lua
local locked = gt.shared_get("target_locked", false)
```

---

### gt.shared_delete(key)

删除共享变量。

**返回值：** 是否删除了已存在的变量

---

### gt.shared_clear(prefix)

清空共享变量。传入 `prefix` 时只清理对应前缀；不传或传空字符串时清空全部。

**返回值：** 清理数量

---

### gt.shared_incr(key, delta)

原子递增共享数值。

**参数：**
- `key` (string): 共享变量名
- `delta` (number，可选): 增量，默认 `1`

**返回值：** 递增后的数值

---

## 鼠标操作

> 以下是旧版 API，为保持兼容性而保留。推荐使用上面的统一 API。

### gt.mouse_move(x, y)

将鼠标移动到指定的绝对坐标。

**参数：**
- `x` (number): 目标 X 坐标（像素）
- `y` (number): 目标 Y 坐标（像素）

**返回值：** 无

**示例：**
```lua
-- 移动鼠标到坐标 (500, 300)
gt.mouse_move(500, 300)
```

---

### gt.mouse_move_relative(dx, dy)

相对当前位置移动鼠标。

**参数：**
- `dx` (number): X 方向偏移量（正值向右，负值向左）
- `dy` (number): Y 方向偏移量（正值向下，负值向上）

**返回值：** 无

**示例：**
```lua
-- 向右移动 100 像素，向下移动 50 像素
gt.mouse_move_relative(100, 50)

-- 向左移动 50 像素
gt.mouse_move_relative(-50, 0)
```

---

### gt.mouse_move_smooth(x, y, duration_ms)

平滑移动鼠标到指定位置（带缓动效果）。

**参数：**
- `x` (number): 目标 X 坐标
- `y` (number): 目标 Y 坐标
- `duration_ms` (number): 移动持续时间（毫秒），默认 100ms

**返回值：** 无

**示例：**
```lua
-- 500 毫秒内平滑移动到 (800, 600)
gt.mouse_move_smooth(800, 600, 500)
```

---

### gt.mouse_get_pos()

获取当前鼠标位置。

**参数：** 无

**返回值：**
- `x` (number): 当前 X 坐标
- `y` (number): 当前 Y 坐标

**示例：**
```lua
local x, y = gt.mouse_get_pos()
gt.log("鼠标位置: " .. x .. ", " .. y)
```

---

### gt.mouse_click(button)

模拟鼠标点击（按下并释放）。

**参数：**
- `button` (string): 鼠标按钮，可选值：
  - `"left"` 或 `"lbutton"`: 左键
  - `"right"` 或 `"rbutton"`: 右键
  - `"middle"` 或 `"mbutton"`: 中键
  - `"x1"` 或 `"xbutton1"`: 侧键1
  - `"x2"` 或 `"xbutton2"`: 侧键2

**返回值：** 无

**示例：**
```lua
-- 左键点击
gt.mouse_click("left")

-- 右键点击
gt.mouse_click("right")

-- 中键点击
gt.mouse_click("middle")
```

---

### gt.mouse_down(button)

模拟鼠标按键按下（不释放）。

**参数：**
- `button` (string): 鼠标按钮（同 mouse_click）

**返回值：** 无

**示例：**
```lua
-- 按下左键（用于拖拽操作）
gt.mouse_down("left")
gt.mouse_move_relative(100, 0)
gt.mouse_up("left")
```

---

### gt.mouse_up(button)

模拟鼠标按键释放。

**参数：**
- `button` (string): 鼠标按钮（同 mouse_click）

**返回值：** 无

---

### gt.mouse_scroll(direction, amount)

模拟鼠标滚轮滚动。

**参数：**
- `direction` (string): 滚动方向，`"up"` 或 `"down"`
- `amount` (number): 滚动量，默认 120（一个滚动单位）

**返回值：** 无

**示例：**
```lua
-- 向上滚动
gt.mouse_scroll("up", 120)

-- 向下滚动 3 个单位
gt.mouse_scroll("down", 360)
```

---

## 键盘操作

### gt.key_press(key)

模拟按键（按下并释放）。

**参数：**
- `key` (string): 按键名称，支持：
  - 字母: `"a"` - `"z"`
  - 数字: `"0"` - `"9"`
  - 功能键: `"f1"` - `"f12"`
  - 特殊键: `"space"`, `"enter"`, `"tab"`, `"escape"`, `"backspace"`, `"delete"`, `"insert"`
  - 方向键: `"up"`, `"down"`, `"left"`, `"right"`
  - 修饰键: `"ctrl"`, `"alt"`, `"shift"`, `"win"`
  - 导航键: `"home"`, `"end"`, `"pageup"`, `"pagedown"`
  - 小键盘: `"numpad0"` - `"numpad9"`, `"multiply"`, `"add"`, `"subtract"`, `"decimal"`, `"divide"`

**返回值：** 无

**示例：**
```lua
-- 按下 A 键
gt.key_press("a")

-- 按下 F5
gt.key_press("f5")

-- 按下空格
gt.key_press("space")
```

---

### gt.key_down(key)

模拟按键按下（不释放）。

**参数：**
- `key` (string): 按键名称

**返回值：** 无

**示例：**
```lua
-- 按住 Shift
gt.key_down("shift")
gt.key_press("a")  -- 输入大写 A
gt.key_up("shift")
```

---

### gt.key_up(key)

模拟按键释放。

**参数：**
- `key` (string): 按键名称

**返回值：** 无

---

### gt.key_combo(key1, key2, ...)

模拟组合键（同时按下多个键）。

**参数：**
- `key1, key2, ...` (string): 多个按键名称

**返回值：** 无

**示例：**
```lua
-- Ctrl+C 复制
gt.key_combo("ctrl", "c")

-- Ctrl+Shift+S 另存为
gt.key_combo("ctrl", "shift", "s")

-- Alt+F4 关闭窗口
gt.key_combo("alt", "f4")
```

---

### gt.type_text(text)

输入文本（支持 Unicode 字符）。

**参数：**
- `text` (string): 要输入的文本

**返回值：** 无

**示例：**
```lua
-- 输入英文
gt.type_text("Hello World")

-- 输入中文
gt.type_text("你好世界")
```

---

## 驱动级操作

驱动级操作使用当前驱动后端。支持 `nc`、`kminput`、`logitech`、`dd` 四种模式。

### gt.driver_enabled()

检查驱动级是否已启用。

**返回值：**
- `enabled` (boolean): 是否启用

**示例：**
```lua
if gt.driver_enabled() then
    gt.log("驱动级已启用")
else
    gt.log("驱动级未启用")
end
```

---

### gt.get_driver_type()

获取当前驱动后端。

**返回值：**
- `type` (string): `nc`、`kminput`、`logitech` 或 `dd`

**示例：**
```lua
gt.log("当前驱动模式: " .. gt.get_driver_type())
```

---

### gt.set_driver_type(type)

切换当前驱动后端。只接受 `nc`、`kminput`、`logitech`、`dd`。

**参数：**
- `type` (string): 驱动后端名称

**返回值：**
- `ok` (boolean): 是否切换成功
- `current` (string): 当前实际驱动后端

**示例：**
```lua
local ok, current = gt.set_driver_type("kminput")
if ok then
    gt.log("已切换驱动模式: " .. current)
else
    gt.log("驱动模式切换失败，当前模式: " .. current)
end
```

---

### gt.driver_key_press(key)

使用驱动级模拟按键。

**参数：**
- `key` (string): 按键名称

**返回值：** 无

**示例：**
```lua
if gt.driver_enabled() then
    gt.driver_key_press("a")
end
```

---

### gt.driver_key_down(key)

使用驱动级按下按键。

**参数：**
- `key` (string): 按键名称

**返回值：** 无

---

### gt.driver_key_up(key)

使用驱动级释放按键。

**参数：**
- `key` (string): 按键名称

**返回值：** 无

---

### gt.driver_mouse_move(x, y)

使用驱动级移动鼠标（绝对坐标）。

**参数：**
- `x` (number): 目标 X 坐标
- `y` (number): 目标 Y 坐标

**返回值：** 无

---

### gt.driver_mouse_move_relative(dx, dy)

使用驱动级相对移动鼠标。

**参数：**
- `dx` (number): X 偏移量
- `dy` (number): Y 偏移量

**返回值：** 无

**示例：**
```lua
-- 用于 Apex 等游戏的压枪脚本
function recoil_control()
    gt.driver_mouse_move_relative(0, 2)
    gt.sleep(6.6)
end
```

---

### gt.driver_mouse_click(button)

使用驱动级点击鼠标。

**参数：**
- `button` (string): 鼠标按钮 (`"left"`, `"right"`, `"middle"`)

**返回值：** 无

---

## 虚拟手柄 API

这组 API 基于虚拟手柄输出，适合需要向游戏或程序发送 Xbox 风格手柄按键的场景。

### gt.gamepad_available()

检查虚拟手柄是否可用。

**返回值：**
- `available` (boolean): 是否可用

**示例：**
```lua
if gt.gamepad_available() then
  gt.log("虚拟手柄可用")
else
  gt.log("虚拟手柄不可用")
end
```

### gt.gamepad_button(button_name, action)

发送虚拟手柄按键 down / up。

**参数：**
- `button_name` (string): 手柄按键名，例如：
  - `pad_a`, `pad_b`, `pad_x`, `pad_y`
  - `pad_lb`, `pad_rb`, `pad_lt`, `pad_rt`
  - `pad_ls`, `pad_rs`
  - `pad_start`, `pad_select`
  - `pad_dpad_up`, `pad_dpad_down`, `pad_dpad_left`, `pad_dpad_right`
- `action` (string): `down` / `up`

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例 1：单独按下 / 抬起**
```lua
gt.gamepad_button("pad_a", "down")
gt.sleep(80)
gt.gamepad_button("pad_a", "up")
```

**示例 2：长按扳机**
```lua
gt.gamepad_button("pad_rt", "down")
gt.sleep(300)
gt.gamepad_button("pad_rt", "up")
```

**示例 3：方向键组合**
```lua
gt.gamepad_button("pad_dpad_right", "down")
gt.sleep(60)
gt.gamepad_button("pad_dpad_right", "up")
```

### gt.gamepad_press(button_name, hold_ms)

虚拟手柄按下并释放。

**参数：**
- `button_name` (string): 手柄按键名
- `hold_ms` (number, 可选): 保持时间（毫秒），默认 50

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例 1：按一次 A**
```lua
gt.gamepad_press("pad_a")
```

**示例 2：按住 RT 120ms**
```lua
gt.gamepad_press("pad_rt", 120)
```

**示例 3：连按 X 三次**
```lua
for i = 1, 3 do
  gt.gamepad_press("pad_x", 40)
  gt.sleep(80)
end
```

### gt.gamepad_reset()

重置虚拟手柄所有状态，释放所有已按下按键。

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
local ok, err = gt.gamepad_reset()
if not ok then
  gt.log("重置虚拟手柄失败: " .. tostring(err))
end
```

---

## 延时函数

### gt.sleep(ms)

暂停执行指定毫秒数。

**参数：**
- `ms` (number): 延时毫秒数（支持小数）

**返回值：** 无

**示例：**
```lua
-- 延时 100 毫秒
gt.sleep(100)

-- 延时 6.6 毫秒（高精度）
gt.sleep(6.6)
```

---

### gt.sleep_random(min_ms, max_ms)

随机延时（在指定范围内）。

**参数：**
- `min_ms` (number): 最小延时（毫秒）
- `max_ms` (number): 最大延时（毫秒）

**返回值：** 无

**示例：**
```lua
-- 随机延时 50-150 毫秒
gt.sleep_random(50, 150)
```

---

### gt.loop(count, interval_ms, callback_name)

循环调用当前脚本里的函数。

**参数：**
- `count` (number): 执行次数；`0` 表示无限循环直到脚本停止
- `interval_ms` (number): 每次调用之间的等待时间（毫秒）；可为 `0`
- `callback_name` (string): 要调用的 Lua 函数名

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**注意事项：**
1. 这是同步循环，会阻塞当前脚本执行流，直到循环结束或脚本被停止。
2. `callback_name` 必须是当前脚本里已经定义好的函数名。
3. 如果需要后台定时触发且不阻塞主循环，优先使用 `gt.set_interval(...)`。

**示例 1：固定次数执行**
```lua
function say_hi()
  gt.log("hi")
end

gt.loop(5, 1000, "say_hi")
```

**示例 2：无限循环轮询**
```lua
function watch_hp()
  if gt.check_color(100, 200, 255, 0, 0, 20) then
    gt.reminder("血量告急", 1500)
  end
end

gt.loop(0, 200, "watch_hp")
```

**示例 3：有限次数点击**
```lua
function do_click()
  gt.click("left")
end

local ok, err = gt.loop(10, 50, "do_click")
if not ok then
  gt.log("loop 执行失败: " .. tostring(err))
end
```

---

## 宏调用

Lua 可以直接调用 GUI 界面上录制的宏。

### gt.run_macro(hotkey)

运行 GUI 上绑定到指定热键的宏。

> **注意**：
> - 如果脚本全局开关被禁用，调用此函数会自动启用脚本
> - 会根据宏的执行模式（once/loop/hold/mapping）自动处理

**参数：**
- `hotkey` (string): 热键名称（如 "f1", "mouse_left", "ctrl+a" 等）

**返回值：**
- `success` (boolean): 是否成功启动
- `error` (string|nil): 错误信息（失败时）

**执行模式说明：**
- `once`: 执行一次
- `loop`: 切换循环状态（开始/停止）
- `hold`: 启动循环执行
- `mapping`: 执行 down 动作

**示例：**
```lua
-- 运行绑定到 F1 的宏
local ok, err = gt.run_macro("f1")
if ok then
    gt.log("宏已启动")
else
    gt.log("启动失败: " .. err)
end

-- 运行绑定到鼠标左键的宏
gt.run_macro("mouse_left")

-- 运行绑定到组合键的宏
gt.run_macro("ctrl+shift+1")
```

---

### gt.stop_macro(hotkey)

停止正在执行的宏（用于 loop/hold 模式）。

**参数：**
- `hotkey` (string): 热键名称

**返回值：**
- `success` (boolean): 是否成功停止

**示例：**
```lua
-- 停止 loop/hold 模式的宏
gt.stop_macro("1")

-- 配合 run_macro 使用
gt.run_macro("1")   -- 启动 loop 宏
gt.sleep(5000)      -- 运行 5 秒
gt.stop_macro("1")  -- 停止宏
```

---

### gt.list_macros()

列出所有可用的宏（已在 GUI 上配置的热键）。

**返回值：**
- `macros` (table): 热键名称数组

**示例：**
```lua
local macros = gt.list_macros()
gt.log("可用宏数量: " .. #macros)

for i, hotkey in ipairs(macros) do
    gt.log("宏 " .. i .. ": " .. hotkey)
end
```

---

### gt.has_macro(hotkey)

检查指定热键是否有配置宏。

**参数：**
- `hotkey` (string): 热键名称

**返回值：**
- `exists` (boolean): 是否存在

**示例：**
```lua
if gt.has_macro("f1") then
    gt.log("F1 已配置宏")
    gt.run_macro("f1")
else
    gt.log("F1 未配置宏")
end
```

---

### gt.get_macro_info(hotkey)

获取宏的详细信息。

**参数：**
- `hotkey` (string): 热键名称

**返回值：**
- `info` (table|nil): 宏信息，包含：
  - `hotkey` (string): 热键名称
  - `action_count` (number): 动作数量
  - `block_key` (boolean): 是否阻断原始按键
  - `execution_mode` (string): 执行模式（once/loop/hold）

**示例：**
```lua
local info = gt.get_macro_info("f1")
if info then
    gt.log("热键: " .. info.hotkey)
    gt.log("动作数: " .. info.action_count)
    gt.log("执行模式: " .. info.execution_mode)
else
    gt.log("宏不存在")
end
```

---

## 宏库 API

宏库是独立于热键绑定的宏存储，可以通过名称调用。

### gt.run_macro_by_name(name)

按名称运行宏库中的宏。

**参数：**
- `name` (string): 宏名称

**返回值：**
- `success` (boolean): 是否成功启动
- `error` (string|nil): 错误信息（失败时）

**示例：**
```lua
-- 运行名为 "连点器" 的宏
local ok, err = gt.run_macro_by_name("连点器")
if ok then
    gt.log("宏已启动")
else
    gt.log("启动失败: " .. err)
end
```

---

### gt.list_macro_library()

列出宏库中的所有宏名称。

**返回值：**
- `names` (table): 宏名称数组

**示例：**
```lua
local macros = gt.list_macro_library()
gt.log("宏库中共有 " .. #macros .. " 个宏")

for i, name in ipairs(macros) do
    gt.log("宏 " .. i .. ": " .. name)
end
```

---

### gt.has_macro_by_name(name)

检查宏库中是否存在指定名称的宏。

**参数：**
- `name` (string): 宏名称

**返回值：**
- `exists` (boolean): 是否存在

**示例：**
```lua
if gt.has_macro_by_name("压枪脚本") then
    gt.run_macro_by_name("压枪脚本")
else
    gt.log("宏不存在")
end
```

---

### gt.get_macro_library_info(name)

获取宏库中宏的详细信息。

**参数：**
- `name` (string): 宏名称

**返回值：**
- `info` (table|nil): 宏信息，包含：
  - `id` (string): 宏 ID
  - `name` (string): 宏名称
  - `description` (string): 描述
  - `action_count` (number): 动作数量
  - `hotkey` (string): 绑定的热键（可能为空）
  - `execution_mode` (string): 执行模式

**示例：**
```lua
local info = gt.get_macro_library_info("连点器")
if info then
    gt.log("宏名: " .. info.name)
    gt.log("动作数: " .. info.action_count)
    gt.log("模式: " .. info.execution_mode)
end
```

---

### gt.stop_macro_by_name(name)

停止宏库中正在循环执行的宏。

**参数：**
- `name` (string): 宏名称

**返回值：**
- `success` (boolean): 是否成功停止

**示例：**
```lua
-- 停止循环执行的宏
gt.stop_macro_by_name("连点器")
```

---

## 设备动作 API

设备动作指的是“设备控制”页里当前已经保存的键盘、鼠标、手柄动作绑定。  
这组 API 调用的是当前最新配置，不是宏库快照。

### gt.list_device_bindings(kind)

列出当前设备动作。

**参数：**
- `kind` (string, 可选): `keyboard` / `mouse` / `gamepad`

**返回值：**
- `items` (table): 设备动作数组。每项常见字段：
  - `kind` (string)
  - `target` (string)
  - `displayTarget` (string)
  - `actionCount` (number)
  - `executionMode` (string)
  - `randomDelayEnabled` (boolean)
  - `randomDelayMin` (number)
  - `randomDelayMax` (number)
  - `loopCount` (number)
  - `loopDurationSeconds` (number)
  - `sourceMacroName` (string|nil)
  - `entitlementLocked` (boolean)
  - `entitlementReason` (string|nil)

**示例：**
```lua
local items = gt.list_device_bindings("keyboard")
gt.log("键盘动作数量: " .. tostring(#items))

for i, item in ipairs(items) do
  gt.log(string.format(
    "[%d] %s -> %s (%d 个动作, 模式=%s)",
    i,
    tostring(item.kind),
    tostring(item.displayTarget or item.target),
    tonumber(item.actionCount or 0),
    tostring(item.executionMode or "once")
  ))
end
```

### gt.has_device_binding(kind, target)

检查指定设备动作是否存在。

**参数：**
- `kind` (string): `keyboard` / `mouse` / `gamepad`
- `target` (string): 绑定目标名

**返回值：**
- `exists` (boolean)

**示例：**
```lua
if gt.has_device_binding("mouse", "mouse_left") then
  gt.log("已找到鼠标左键动作")
end
```

### gt.run_device_binding(kind, target)

立即执行当前设备动作。

**参数：**
- `kind` (string): `keyboard` / `mouse` / `gamepad`
- `target` (string): 绑定目标名

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
local ok, err = gt.run_device_binding("keyboard", "key_q")
if not ok then
  gt.log("执行设备动作失败: " .. tostring(err))
end
```

**结合定时器示例：**
```lua
function cast_main_skill()
  local ok, err = gt.run_device_binding("keyboard", "key_q")
  if not ok then
    gt.log("执行主技能失败: " .. tostring(err))
  end
end

gt.set_interval("main_skill_loop", 5000, "cast_main_skill")
```

---

## 热键绑定

### gt.bind_hotkey(hotkey, callback_name)

绑定热键到 Lua 函数（单次执行模式）。按下热键时执行一次回调函数。

**参数：**
- `hotkey` (string): 热键组合，如 `"f1"`, `"ctrl+a"`, `"alt+shift+f5"`
- `callback_name` (string): 回调函数名称

**返回值：**
- `success` (boolean): 是否绑定成功

**示例：**
```lua
function my_macro()
    gt.log("热键触发！")
    gt.mouse_click("left")
end

gt.bind_hotkey("f1", "my_macro")
```

---

### gt.bind_hotkey_loop(hotkey, callback_name, interval_ms)

绑定热键到循环执行模式（Toggle 模式）。第一次按下开始循环执行，再次按下停止循环。

**参数：**
- `hotkey` (string): 热键组合
- `callback_name` (string): 回调函数名称
- `interval_ms` (number): 循环间隔（毫秒），默认 50ms

**返回值：**
- `success` (boolean): 是否绑定成功

**示例：**
```lua
-- 自动连点器：按 F1 开始连点，再按 F1 停止
function auto_click()
    gt.click("left")
end

gt.bind_hotkey_loop("f1", "auto_click", 50)
gt.log("按 F1 开始/停止自动连点")
```

---

### gt.toggle_hotkey_loop(hotkey)

手动切换热键循环状态。

**参数：**
- `hotkey` (string): 热键组合

**返回值：**
- `running` (boolean): 切换后的状态（true=正在运行，false=已停止）

**示例：**
```lua
-- 手动切换循环状态
local is_running = gt.toggle_hotkey_loop("f1")
if is_running then
    gt.log("循环已启动")
else
    gt.log("循环已停止")
end
```

---

### gt.stop_hotkey_loop(hotkey)

停止指定热键的循环。

**参数：**
- `hotkey` (string): 热键组合

**返回值：** 无

**示例：**
```lua
gt.stop_hotkey_loop("f1")
```

---

### gt.stop_all_loops()

停止所有正在运行的热键循环。

**参数：** 无

**返回值：** 无

**示例：**
```lua
-- 紧急停止所有循环
gt.stop_all_loops()
```

---

### gt.is_loop_running(hotkey)

检查指定热键的循环是否正在运行。

**参数：**
- `hotkey` (string): 热键组合

**返回值：**
- `running` (boolean): 是否正在运行

**示例：**
```lua
if gt.is_loop_running("f1") then
    gt.log("F1 循环正在运行")
else
    gt.log("F1 循环已停止")
end
```

---

### gt.unbind_hotkey(hotkey)

解除热键绑定（同时停止循环）。

**参数：**
- `hotkey` (string): 热键组合

**返回值：** 无

**示例：**
```lua
gt.unbind_hotkey("f1")
```

---

### gt.is_key_pressed(key)

检查指定按键是否正在被按下。

**参数：**
- `key` (string): 按键名称

**返回值：**
- `pressed` (boolean): 是否按下

**示例：**
```lua
-- 按住 F1 时持续点击
while gt.is_key_pressed("f1") do
    gt.mouse_click("left")
    gt.sleep(50)
end
```

---

## 进程限制热键

热键可以设置为只在特定进程（游戏/应用程序）处于前台时才生效。

### gt.set_hotkey_process(hotkey, process1, process2, ...)

设置热键只在指定进程生效。当设置后，热键只有在指定的进程窗口处于前台时才会触发。

**参数：**
- `hotkey` (string): 热键名称
- `process1, process2, ...` (string): 一个或多个进程名称（如 `"r5apex.exe"`, `"notepad.exe"`）

**返回值：**
- `success` (boolean): 是否设置成功

**示例：**
```lua
-- 绑定热键
function recoil_control()
    gt.move(0, 2, true, true)
    gt.sleep(6.6)
end

gt.bind_hotkey_loop("lbutton", "recoil_control", 7)

-- 设置只在 Apex Legends 生效
gt.set_hotkey_process("lbutton", "r5apex.exe")
gt.log("压枪脚本只在 Apex 中生效")
```

**多进程示例：**
```lua
-- 设置在多个游戏中生效
gt.set_hotkey_process("f1", "r5apex.exe", "csgo.exe", "valorant.exe")
```

---

### gt.clear_hotkey_process(hotkey)

清除热键的进程限制，使其在任何进程中都能生效。

**参数：**
- `hotkey` (string): 热键名称

**返回值：** 无

**示例：**
```lua
-- 清除进程限制，恢复全局生效
gt.clear_hotkey_process("f1")
```

---

### gt.get_hotkey_process(hotkey)

获取热键的进程限制列表。

**参数：**
- `hotkey` (string): 热键名称

**返回值：**
- `processes` (table|nil): 进程名称数组，如果没有限制则返回 nil

**示例：**
```lua
local procs = gt.get_hotkey_process("f1")
if procs then
    gt.log("F1 热键限制进程：")
    for _, p in ipairs(procs) do
        gt.log("  - " .. p)
    end
else
    gt.log("F1 热键没有进程限制（全局生效）")
end
```

---

### gt.get_foreground_process()

获取当前前台窗口的进程名称。

**参数：** 无

**返回值：**
- `process_name` (string|nil): 进程名称（小写），获取失败时返回 nil

**示例：**
```lua
local proc = gt.get_foreground_process()
if proc then
    gt.log("当前前台进程: " .. proc)
    
    -- 根据进程自动选择配置
    if proc == "r5apex.exe" then
        gt.log("检测到 Apex Legends，加载压枪配置")
    elseif proc == "notepad.exe" then
        gt.log("检测到记事本，加载文本宏")
    end
else
    gt.log("无法获取前台进程")
end
```

---

### 进程限制完整示例

```lua
-- Apex Legends 专用压枪脚本
-- 只在游戏中生效，防止在其他程序中误触发

-- R301 压枪函数
function r301_recoil()
    gt.move(0, 3, true, true)  -- 驱动级相对移动
end

-- 绑定到鼠标左键，7ms 间隔
gt.bind_hotkey_loop("lbutton", "r301_recoil", 7)

-- 设置只在 Apex 中生效
gt.set_hotkey_process("lbutton", "r5apex.exe")

-- 添加状态检测热键
function show_status()
    local proc = gt.get_foreground_process()
    gt.log("当前进程: " .. (proc or "未知"))
    
    local filter = gt.get_hotkey_process("lbutton")
    if filter then
        gt.log("左键限制进程: " .. table.concat(filter, ", "))
    else
        gt.log("左键无进程限制")
    end
end

gt.bind_hotkey("f2", "show_status")

gt.log("=== Apex 压枪脚本 ===")
gt.log("左键压枪只在 r5apex.exe 中生效")
gt.log("按 F2 查看状态")
```

---

## 取色识别

### gt.get_pixel_color(x, y)

获取指定坐标的像素颜色。

坐标语义：使用逻辑坐标，与 UI 取色/框选区域保持一致。

**参数：**
- `x` (number): X 坐标
- `y` (number): Y 坐标

**返回值：**
- `r` (number): 红色分量 (0-255)
- `g` (number): 绿色分量 (0-255)
- `b` (number): 蓝色分量 (0-255)

**示例：**
```lua
local r, g, b = gt.get_pixel_color(100, 200)
gt.log(string.format("颜色: RGB(%d, %d, %d)", r, g, b))
```

---

### gt.check_color(x, y, r, g, b, tolerance)

检查指定坐标的颜色是否匹配目标颜色。

坐标语义：使用逻辑坐标，与 UI 取色/框选区域保持一致。

**参数：**
- `x` (number): X 坐标
- `y` (number): Y 坐标
- `r` (number): 目标红色分量
- `g` (number): 目标绿色分量
- `b` (number): 目标蓝色分量
- `tolerance` (number): 容差值 (0-255)

**返回值：**
- `matched` (boolean): 是否匹配

**示例：**
```lua
-- 检查 (100, 200) 位置是否为红色（容差 20）
if gt.check_color(100, 200, 255, 0, 0, 20) then
    gt.log("检测到红色！")
end
```

---

### gt.check_colors(points)

检查多个颜色点是否全部匹配。

坐标语义：颜色点使用逻辑坐标。

**参数：**
- `points` (table): 颜色点数组，每个元素包含 `{x, y, r, g, b, tolerance}`

**返回值：**
- `matched` (boolean): 是否全部匹配

**示例：**
```lua
local points = {
    {x = 100, y = 200, r = 255, g = 0, b = 0, tolerance = 20},
    {x = 150, y = 250, r = 0, g = 255, b = 0, tolerance = 20},
    {x = 200, y = 300, r = 0, g = 0, b = 255, tolerance = 20},
}

if gt.check_colors(points) then
    gt.log("所有颜色点匹配！")
end
```

---

### gt.check_saved_colors(name_or_data)

按视觉识别页里的取色配置名称检测已保存的取色模板，或直接传入颜色点原数据检测。

**参数：**
- `name_or_data` (string|table): 取色配置名称，或 `{ color_points = {...}, search_region = {...}, step = 1 }`
- `color_points` 中每个颜色点包含 `{x, y, target_r, target_g, target_b, tolerance, is_physical}`，也兼容 `{x, y, r, g, b, tolerance}`
- `search_region` 可选；填写后会以第一个颜色点为锚点，在区域内按相对位置查找整组颜色点
- `step` 可选；范围查找步长，默认 1，数值越小越准

**返回值：**
- `matched` (boolean): 是否匹配
- `x` (number|nil): 范围查找匹配到的锚点 X 坐标
- `y` (number|nil): 范围查找匹配到的锚点 Y 坐标

**示例：**
```lua
if gt.check_saved_colors("技能可用") then
    gt.key_press("1")
    gt.log("技能可用")
end

local ok, x, y = gt.check_saved_colors({
    color_points = {
        { x = 100, y = 200, target_r = 255, target_g = 80, target_b = 40, tolerance = 12 },
        { x = 120, y = 205, target_r = 250, target_g = 76, target_b = 38, tolerance = 12 },
    },
    search_region = { x = 80, y = 160, width = 360, height = 240 },
    step = 1,
})
if ok then
    gt.log("颜色匹配成功")
    if x then gt.mouse_move(x, y) end
end
```

---

### gt.find_color(x, y, width, height, r, g, b, tolerance, step)

在指定区域内查找目标颜色，返回第一个匹配坐标。

**参数：**
- `x` (number): 搜索区域左上角 X
- `y` (number): 搜索区域左上角 Y
- `width` (number): 搜索区域宽度
- `height` (number): 搜索区域高度
- `r` (number): 目标颜色 R
- `g` (number): 目标颜色 G
- `b` (number): 目标颜色 B
- `tolerance` (number): 容差值
- `step` (number): 采样步长；`1` 最精确，值越大扫描越快

**返回值：**
- `match_x` (number|nil): 匹配 X
- `match_y` (number|nil): 匹配 Y

**示例 1：基础查找**
```lua
local x, y = gt.find_color(800, 400, 320, 180, 255, 210, 80, 16, 2)
if x then
  gt.log(string.format("找到颜色: %d,%d", x, y))
end
```

**示例 2：找到后点击**
```lua
local x, y = gt.find_color(600, 300, 500, 300, 0, 255, 0, 20, 3)
if x and y then
  gt.move(x, y, false)
  gt.click("left", "click")
end
```

**示例 3：结合循环轮询**
```lua
function seek_enemy_marker()
  local x, y = gt.find_color(700, 350, 400, 240, 255, 64, 64, 18, 4)
  if x then
    gt.log("已发现目标标记")
  end
end

gt.loop(0, 100, "seek_enemy_marker")
```

### gt.find_color_region(region, r, g, b, tolerance, step)

使用区域表在屏幕上查找颜色。

**参数：**
- `region` (table): `{ x, y, width, height }`
- `r` (number): 目标颜色 R
- `g` (number): 目标颜色 G
- `b` (number): 目标颜色 B
- `tolerance` (number): 容差值
- `step` (number): 采样步长

**返回值：**
- `match_x` (number|nil): 匹配 X
- `match_y` (number|nil): 匹配 Y

**示例 1：基础区域表**
```lua
local region = { x = 900, y = 500, width = 240, height = 160 }
local x, y = gt.find_color_region(region, 255, 64, 64, 18, 4)
if x then
  gt.log("区域内找到目标颜色")
end
```

**示例 2：找到后移动鼠标**
```lua
local x, y = gt.find_color_region(
  { x = 500, y = 280, width = 600, height = 360 },
  255, 220, 90, 12, 2
)

if x and y then
  gt.mouse_move(x, y)
end
```

**示例 3：与取色模板配合**
```lua
function check_loot_light()
  local x, y = gt.find_color_region(
    { x = 760, y = 420, width = 420, height = 240 },
    255, 255, 120, 20, 3
  )
  if x then
    gt.reminder("发现可交互发光点", 1200)
  end
end

gt.loop(0, 120, "check_loot_light")
```

---

## 截图功能

### gt.screenshot(x, y, width, height, filename)

截取屏幕区域并保存为 PNG 文件。

坐标语义：使用逻辑坐标，与 UI 框选区域保持一致。

**参数：**
- `x` (number): 起始 X 坐标
- `y` (number): 起始 Y 坐标
- `width` (number): 宽度
- `height` (number): 高度
- `filename` (string): 保存路径

**返回值：**
- `success` (boolean): 是否成功
- `error` (string|nil): 错误信息（失败时）

**示例：**
```lua
local ok, err = gt.screenshot(0, 0, 1920, 1080, "C:/screenshots/screen.png")
if ok then
    gt.log("截图已保存")
else
    gt.log("截图失败: " .. err)
end
```

---

### gt.screenshot_base64(x, y, width, height)

截取屏幕区域并返回 Base64 编码的 PNG 图像。

坐标语义：使用逻辑坐标，与 UI 框选区域保持一致。

**参数：**
- `x` (number): 起始 X 坐标
- `y` (number): 起始 Y 坐标
- `width` (number): 宽度
- `height` (number): 高度

**返回值：**
- `base64` (string|nil): Base64 编码的图像，失败时返回 nil

**示例：**
```lua
local img = gt.screenshot_base64(100, 100, 200, 200)
if img then
    gt.log("截图成功，长度: " .. #img)
end
```

---

## 图像识别

### gt.find_image(template_path, region)

在屏幕上搜索指定图像。

坐标语义：`region` 使用逻辑坐标。

**参数：**
- `template_path` (string): 模板图像路径
- `region` (table, 可选): 搜索区域 `{x, y, width, height}`

**返回值：**
- `x` (number|nil): 找到的 X 坐标，未找到返回 nil
- `y` (number|nil): 找到的 Y 坐标
- `confidence` (number|nil): 匹配置信度 (0-1)

**示例：**
```lua
local x, y, conf = gt.find_image("C:/templates/button.png")
if x then
    gt.log(string.format("找到图像: (%d, %d), 置信度: %.2f", x, y, conf))
    gt.mouse_move(x, y)
    gt.mouse_click("left")
end
```

---

### gt.find_saved_image(name_or_data, region)

按视觉识别页里的识图配置名称查找已保存的识图模板，或直接传入图片原数据查找。

坐标语义：`region` 和 `search_region` 使用逻辑坐标；省略时使用模板保存的搜索范围或全屏。

**参数：**
- `name_or_data` (string|table): 识图配置名称，或 `{ image_encrypted = "gtimg1:...", match_threshold = 0.8, scale_min = 0.8, scale_max = 1.2, search_region = {...} }`
- `region` (table, 可选): 临时搜索区域 `{x, y, width, height}`；需要按物理屏幕坐标截图时可附加 `source_x, source_y, source_width, source_height`

`image_encrypted` 是原始图片 Lua 模板推荐字段，执行时自动解密；`image_base64` 仍保留兼容旧脚本。

**返回值：**
- `x` (number|nil): 找到的中心 X 坐标，未找到返回 nil
- `y` (number|nil): 找到的中心 Y 坐标
- `confidence` (number|nil): 匹配置信度 (0-1)

**示例：**
```lua
local x, y, conf = gt.find_saved_image("确认按钮", { x = 600, y = 300, width = 800, height = 500 })
if x then
    gt.log(string.format("找到保存模板: (%d, %d), 置信度: %.2f", x, y, conf))
    gt.mouse_move(x, y)
    gt.mouse_click("left")
end

local image = {
    image_encrypted = [[gtimg1:...]],
    match_threshold = 0.8,
    scale_min = 0.8,
    scale_max = 1.2,
    search_region = { x = 600, y = 300, width = 800, height = 500 },
}
local rawX, rawY, rawScore = gt.find_saved_image(image)
if rawX then
    gt.log(string.format("找到图片: (%d, %d), 置信度: %.2f", rawX, rawY, rawScore))
end
```

---

### gt.image_match(template_path, x, y, width, height, threshold)

在指定区域进行图像匹配。

坐标语义：区域参数使用逻辑坐标。

**参数：**
- `template_path` (string): 模板图像路径
- `x` (number): 区域起始 X
- `y` (number): 区域起始 Y
- `width` (number): 区域宽度
- `height` (number): 区域高度
- `threshold` (number): 匹配阈值 (0-1)，默认 0.9

**返回值：**
- `matched` (boolean): 是否匹配
- `confidence` (number): 匹配置信度

**示例：**
```lua
local matched, conf = gt.image_match("C:/templates/icon.png", 100, 100, 50, 50, 0.9)
if matched then
    gt.log("图像匹配成功！")
end
```

---

## 系统函数

### gt.get_screen_size()

获取屏幕分辨率。

返回值语义：返回逻辑坐标系下的主屏幕分辨率。

**返回值：**
- `width` (number): 屏幕宽度
- `height` (number): 屏幕高度

**示例：**
```lua
local w, h = gt.get_screen_size()
gt.log(string.format("屏幕分辨率: %dx%d", w, h))
```

---

### gt.get_active_window()

获取当前活动窗口标题。

**返回值：**
- `title` (string): 窗口标题

**示例：**
```lua
local title = gt.get_active_window()
gt.log("当前窗口: " .. title)

-- 检查特定窗口
if title:find("记事本") then
    gt.log("记事本窗口已激活")
end
```

---

### gt.get_foreground_window_rect()

获取当前前台窗口的位置和大小。适合按当前游戏/应用窗口中心计算点击、取色、识图或移动目标。

**返回值：**
- `x` (number): 窗口左上角 X 坐标
- `y` (number): 窗口左上角 Y 坐标
- `width` (number): 窗口宽度
- `height` (number): 窗口高度

**示例：**
```lua
local x, y, w, h = gt.get_foreground_window_rect()
local center_x = x + w / 2
local center_y = y + h / 2

gt.log(string.format("前台窗口中心: %.0f, %.0f", center_x, center_y))
gt.move(center_x, center_y)
```

---

### gt.highlight_rect(x, y, width, height, duration, color, is_physical)

在屏幕指定位置显示一个透明点击穿透的高亮边框，适合调试动态窗口坐标、取色区域和识图区域。

Lua 侧默认按物理屏幕坐标处理，也就是和 `gt.move(...)`、`gt.get_foreground_window_rect()` 计算出的坐标保持一致。需要按 Electron 逻辑坐标显示时，最后一个参数传 `false`。

**参数：**
- `x` (number): 高亮框左上角 X 坐标
- `y` (number): 高亮框左上角 Y 坐标
- `width` (number): 高亮框宽度
- `height` (number): 高亮框高度
- `duration` (number, 可选): 显示时长（毫秒），默认 2000ms
- `color` (string, 可选): 边框颜色，如 `"#ff3355"`；不传时使用循环颜色
- `is_physical` (boolean, 可选): 是否按物理屏幕坐标处理，默认 `true`

也可以传表：

```lua
gt.highlight_rect({
  x = 100,
  y = 100,
  width = 200,
  height = 200,
  duration = 3000,
  color = "#ff3355",
  is_physical = true,
})
```

**返回值：**
- `success` (boolean): 是否成功
- `error_message` (string, 可选): 失败原因

**示例：**

```lua
local wx, wy, ww, wh = gt.get_foreground_window_rect()
if not wx then
  gt.log("No foreground window found")
  return
end

local function round(v)
  return math.floor(v + 0.5)
end

local center_x = round(wx + ww * 0.385)
local center_y = round(wy + wh * 0.06)
local size = 200
local region_x = center_x - size / 2
local region_y = center_y - size / 2

gt.move(center_x, center_y, false, false)
gt.highlight_rect(region_x, region_y, size, size, 3000, "#ff3355")

gt.log(string.format(
  "center: x=%d y=%d, highlight: x=%d y=%d w=%d h=%d",
  center_x, center_y, region_x, region_y, size, size
))
```

---

### gt.hide_highlight()

隐藏当前所有屏幕高亮框。

**返回值：**
- `success` (boolean): 是否成功
- `error_message` (string, 可选): 失败原因

**示例：**

```lua
gt.hide_highlight()
```

---

### gt.is_captcha_input_active()

检查打码输入是否正在独占键鼠。Lua 输入 API 会自动等待打码输入结束；这个函数用于脚本需要主动跳过识别、移动或按键逻辑时判断状态。

**返回值：**
- `active` (boolean): `true` 表示打码输入正在进行

**示例：**
```lua
if gt.is_captcha_input_active() then
    gt.log("打码输入中，暂不执行动作")
    return
end

gt.key("1", "press")
```

---

### gt.log(message)

输出普通日志。

**参数：**
- `message` (string): 日志内容

**返回值：** 无

---

### gt.debug(message)

输出调试日志（需要开启调试模式）。

**参数：**
- `message` (string): 调试信息

**返回值：** 无

---

### gt.reminder(text, duration)

显示 GUI 提醒通知。会在屏幕中央弹出一个透明的提醒窗口，显示指定时间后自动关闭。

**参数：**
- `text` (string): 提醒文本内容
- `duration` (number, 可选): 显示时长（毫秒），默认 3000ms，范围 1000-30000ms

**返回值：**
- `success` (boolean): 是否成功

**示例：**

```lua
-- 显示提醒，默认 3 秒后自动关闭
gt.reminder("任务已完成！")

-- 显示提醒，5 秒后自动关闭
gt.reminder("重要提醒：请注意！", 5000)

-- 显示提醒，10 秒后自动关闭
gt.reminder("长时间提醒内容...", 10000)

-- 在循环中使用提醒
function check_status()
    local hp = get_hp()  -- 假设的函数
    if hp < 30 then
        gt.reminder("警告：血量过低！", 2000)
    end
end

-- 结合热键使用
function notify_action()
    gt.reminder("技能已释放", 1500)
    gt.key("1")
end
gt.bind_hotkey("f1", "notify_action")
```

**注意事项：**
1. 提醒窗口会显示在所有窗口最上层
2. 窗口会自动穿透鼠标事件，不会影响游戏操作
3. 多次调用会替换之前的提醒
4. duration 范围限制在 1-30 秒之间

---

### gt.schedule_reminder(text, delay, duration)

设置定时提醒。在指定延迟时间后显示 GUI 提醒通知。

**参数：**
- `text` (string): 提醒文本内容
- `delay` (number): 延迟时间（毫秒），多久后显示提醒
- `duration` (number, 可选): 显示时长（毫秒），默认 3000ms，范围 1000-30000ms

**返回值：**
- `success` (boolean): 是否成功设置

**示例：**

```lua
-- 30 秒后提醒，显示 5 秒
gt.schedule_reminder("时间到！该做某事了", 30000, 5000)

-- 1 分钟后提醒（60000ms），默认显示 3 秒
gt.schedule_reminder("休息一下吧", 60000)

-- 10 秒后提醒
gt.schedule_reminder("10秒已过", 10000, 2000)

-- 用于技能冷却提醒
function skill_with_reminder()
    gt.key("1")  -- 释放技能
    -- 技能冷却 15 秒，提前 2 秒提醒
    gt.schedule_reminder("技能即将冷却完成！", 13000, 2000)
end
gt.bind_hotkey("f1", "skill_with_reminder")

-- 用于 buff 持续时间提醒
function apply_buff_with_reminder()
    gt.key("2")  -- 施放 buff
    -- buff 持续 30 秒，在 25 秒后提醒续 buff
    gt.schedule_reminder("Buff 即将结束，请续 buff！", 25000, 3000)
end
gt.bind_hotkey("f2", "apply_buff_with_reminder")
```

**注意事项：**
1. 延迟时间可以是任意正整数（毫秒）
2. 此函数立即返回，不会阻塞脚本执行
3. 如果在延迟期间设置了新的提醒，新提醒会覆盖之前的
4. 适用于技能冷却、buff 持续时间、定期提醒等场景

---

### gt.speak(text, voice)

立即播报文本。

**参数：**
- `text` (string): 要播报的内容
- `voice` (string, 可选): 语音名称；不传时使用当前默认语音

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
local ok, err = gt.speak("欢迎使用 GreenTide")
if not ok then
  gt.log("语音播报失败: " .. tostring(err))
end
```

**指定语音示例：**
```lua
local ok, err = gt.speak("目标已出现", "zh-CN-XiaoxiaoNeural")
if not ok then
  gt.log("指定语音播报失败: " .. tostring(err))
end
```

### gt.set_voice(voice)

设置默认语音。

**参数：**
- `voice` (string): 语音名称

**返回值：**
- `success` (boolean)
- `voice` (string|nil): 实际保存后的默认语音

**示例：**
```lua
local ok, voice = gt.set_voice("zh-CN-XiaoxiaoNeural")
if ok then
  gt.log("默认语音已切换为: " .. tostring(voice))
end
```

### gt.get_voice()

获取当前默认语音。

**返回值：**
- `voice` (string): 当前默认语音名称

**示例：**
```lua
local voice = gt.get_voice()
gt.log("当前默认语音: " .. tostring(voice))
```

### gt.list_voices()

列出可用语音。

**返回值：**
- `voices` (table): 语音数组，每项常见字段：
  - `name` (string)
  - `label` (string)
  - `locale` (string)
  - `gender` (string)

**示例：**
```lua
local voices = gt.list_voices()
gt.log("可用语音数量: " .. tostring(#voices))

for _, voice in ipairs(voices) do
  gt.log(string.format(
    "%s | %s | %s",
    tostring(voice.name),
    tostring(voice.label),
    tostring(voice.locale)
  ))
end
```

**完整示例：先列出再切换并播报**
```lua
local voices = gt.list_voices()
if #voices > 0 then
  local targetVoice = voices[1].name
  local ok, savedVoice = gt.set_voice(targetVoice)
  if ok then
    gt.speak("默认语音切换完成", savedVoice)
  end
end
```

---

### gt.msgbox(title, message)

显示消息框。

**参数：**
- `title` (string): 标题
- `message` (string): 内容

**返回值：** 无

**示例：**
```lua
gt.msgbox("提示", "脚本执行完成！")
```

---

### gt.get_time()

获取当前时间戳（毫秒）。

**返回值：**
- `timestamp` (number): Unix 时间戳（毫秒）

**示例：**
```lua
local start = gt.get_time()
-- 执行操作...
local elapsed = gt.get_time() - start
gt.log("耗时: " .. elapsed .. "ms")
```

---

## 全局设置 API

这组 API 会直接修改当前真实配置，并立即让界面与运行态生效。

### gt.get_global_settings()

获取当前全局设置快照。

**返回值：**
- `settings` (table)
- `error` (string|nil)

**常见字段：**
- `keyboardSettings`
- `actionSettings`
- `loadingWindowText`
- `triggerKey`
- `excludedProcesses`
- `gamepadStickSettings`
- `mouseSettings`
- `vibrationSettings`
- `deadzoneSettings`
- `ttsSettings`

**字段说明：**
- `keyboardSettings`
  - `driverKeyEnabled`: 是否启用驱动级按键
  - `driverType`: 驱动后端，`nc` / `kminput` / `logitech` / `dd`
  - `globalKeyboardEnabled`: 全局键盘监听/阻断开关
  - `globalMouseEnabled`: 全局鼠标监听/阻断开关
  - `startupEnabled`: 是否开机启动
  - `desktopShortcutEnabled`: 是否启用桌面快捷方式
  - `mouseTrackRecordingEnabled`: 是否启用鼠标轨迹录制
  - `mouseTrackRecordingMode`: `move` / `hold` / `origin` / `origin_hold`
  - `mouseTrackRecordOrigin`: 录制时是否记录原点
  - `mouseTrackRequireLeftButton`: 录制时是否要求按住左键
  - `autoCompleteInputReleaseEnabled`: 是否自动补齐释放
- `actionSettings`
  - `actionModeEnabled`: 动作模式开关
  - `wsadModeEnabled`: WASD 开关
  - `builtinActionModeEnabled`: 内置动作模式开关
  - `sideWheelToggleEnabled`: 侧键/滚轮切换开关
  - `releaseKeys`: 释放键列表
  - `recognitionFollowHotkeyEnabled`: 识图/取色是否跟随主控热键
- `loadingWindowText`
  - `showText`: 开启提示文本
  - `hideText`: 关闭提示文本
  - `enabled`: 是否显示提示窗口
  - `voiceEnabled`: 是否启用语音提示
  - `loopStatusEnabled`: 是否显示循环状态悬浮层
  - `floatingMacroToggleEnabled`: 是否显示悬浮宏开关
  - `floatingMacroToggleOpacity`: 悬浮宏开关透明度
  - `floatingMacroToggleScale`: 悬浮宏开关缩放
  - `floatingCaptchaToggleEnabled`: 是否显示悬浮打码开关
  - `floatingCaptchaToggleOpacity`: 悬浮打码开关透明度
  - `floatingCaptchaToggleScale`: 悬浮打码开关缩放
  - `gamepadOverlayEnabled`: 是否显示悬浮手柄
  - `gamepadOverlayOpacity`: 悬浮手柄透明度
  - `gamepadOverlayScale`: 悬浮手柄缩放
- `triggerKey`: 全局宏开关键
- `excludedProcesses`
  - `processes`: 排除进程列表
  - `onlySelectedProcesses`: 是否只对选中进程生效
  - `activeProcesses`: 当前实际生效的进程列表
  - `lockedProcesses`: 因额度限制未生效的进程列表
- `gamepadStickSettings`
  - `leftStickMode`: 左摇杆模式
  - `rightStickMode`: 右摇杆模式
  - `wheelSensitivity`: 滚轮灵敏度
  - `wheelInterval`: 滚轮间隔
  - `zoomInButton`: 镜头拉近按键
  - `zoomOutButton`: 镜头拉远按键
  - `hotkeyToggleButton`: 手柄热键开关键
- `mouseSettings`
  - `sensitivity`: 手柄转鼠标灵敏度
  - `acceleration`: 手柄转鼠标加速度
- `vibrationSettings`
  - `enabled`: 是否启用震动
  - `intensity`: 震动强度
- `deadzoneSettings`
  - `deadzone`: 手柄死区值
- `ttsSettings`
  - `voiceName`: 默认语音名称

**示例：**
```lua
local settings, err = gt.get_global_settings()
if err then
  gt.log("读取全局设置失败: " .. tostring(err))
  return
end

gt.log("当前驱动开关: " .. tostring(settings.keyboardSettings.driverKeyEnabled))
gt.log("当前驱动后端: " .. tostring(settings.keyboardSettings.driverType))
gt.log("当前宏开关键: " .. tostring(settings.triggerKey))
```

### gt.update_global_settings(patch)

更新全局设置并立即生效。

**参数：**
- `patch` (table): 只传要修改的字段即可

**常见可更新字段：**
- `keyboard_settings`
- `action_settings`
- `loading_window_text`
- `trigger_key`
- `excluded_processes`
- `gamepad_stick_settings`
- `mouse_settings`
- `vibration_settings`
- `deadzone_settings`
- `tts_settings`

**字段写法说明：**
- Lua 里推荐使用蛇形命名，例如 `keyboard_settings.driver_key_enabled`
- 系统会自动映射到内部字段，例如：
  - `driver_key_enabled -> driverKeyEnabled`
  - `voice_name -> voiceName`
  - `only_selected_processes -> onlySelectedProcesses`

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：切换驱动与全局监听**
```lua
local ok, err = gt.update_global_settings({
  keyboard_settings = {
    driver_key_enabled = true,
    driver_type = "nc",
    global_keyboard_enabled = true,
    global_mouse_enabled = true,
    auto_complete_input_release_enabled = true
  },
  action_settings = {
    wsad_mode_enabled = false
  }
})

if not ok then
  gt.log("更新设置失败: " .. tostring(err))
end
```

**示例：更新提示与语音设置**
```lua
gt.update_global_settings({
  loading_window_text = {
    enabled = true,
    voice_enabled = true,
    show_text = "宏已开启",
    hide_text = "宏已关闭"
  },
  tts_settings = {
    voice_name = "zh-CN-XiaoxiaoNeural"
  }
})
```

### gt.get_trigger_key()

获取当前全局宏开关键。

**返回值：**
- `key` (string|nil)
- `error` (string|nil)

**示例：**
```lua
local key, err = gt.get_trigger_key()
if err then
  gt.log("读取宏开关键失败: " .. tostring(err))
else
  gt.log("当前宏开关键: " .. tostring(key))
end
```

### gt.set_trigger_key(key)

设置或清除全局宏开关键。

**参数：**
- `key` (string): 热键名称；传空字符串表示清除

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
gt.set_trigger_key("F8")
gt.log("已把全局宏开关键设置为 F8")

-- 清除
gt.set_trigger_key("")
```

---

### gt.set_apex_config(sens, zoom_sens)

设置 Apex Legends 灵敏度配置（用于压枪修正）。

**参数：**
- `sens` (number): 游戏灵敏度
- `zoom_sens` (number): 开镜灵敏度

**返回值：** 无

**示例：**
```lua
-- 设置 Apex 灵敏度
gt.set_apex_config(1.0, 1.0)
```

---

### gt.get_apex_modifier()

获取 Apex 灵敏度修正系数。

**返回值：**
- `modifier` (number): 修正系数

**示例：**
```lua
local mod = gt.get_apex_modifier()
gt.log("Apex 修正系数: " .. mod)
```

---

## 鼠标锁定位置 API

这些 API 用于控制主控热键按下时鼠标移动的目标位置。默认情况下，启用动作模式时鼠标会移动到屏幕中心。通过设置偏移量，可以让鼠标移动到屏幕中心的偏移位置。

### gt.set_lock_offset(x, y)

设置鼠标锁定位置偏移（相对于屏幕中心）。

**参数：**
- `x` (number): X 轴偏移量（正值向右，负值向左）
- `y` (number): Y 轴偏移量（正值向下，负值向上）

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 将锁定位置向上偏移 20 像素
gt.set_lock_offset(0, -20)

-- 将锁定位置向右偏移 50 像素，向上偏移 30 像素
gt.set_lock_offset(50, -30)

-- 将锁定位置向左下偏移
gt.set_lock_offset(-100, 50)
```

---

### gt.get_lock_offset()

获取当前鼠标锁定位置偏移。

**参数：** 无

**返回值：**
- `x` (number): X 轴偏移量
- `y` (number): Y 轴偏移量

**示例：**
```lua
local x, y = gt.get_lock_offset()
gt.log(string.format("当前锁定偏移: (%d, %d)", x, y))
```

---

### gt.reset_lock_offset()

重置鼠标锁定位置偏移为 (0, 0)，即屏幕中心。

**参数：** 无

**返回值：** 无

**示例：**
```lua
-- 重置为屏幕中心
gt.reset_lock_offset()
```

---

### gt.set_override(config)

设置 Lua 覆盖态，用于精细控制热键行为。

**参数：**
- `config` (table): 配置表，包含以下可选字段：
  - `offset_x` (number): X 轴偏移量
  - `offset_y` (number): Y 轴偏移量
  - `skip_centering` (boolean): 是否跳过鼠标居中
  - `skip_right_click_lock` (boolean): 是否跳过右键锁定

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 设置偏移并跳过居中
gt.set_override({
    offset_x = 0,
    offset_y = -30,
    skip_centering = true,
    skip_right_click_lock = false
})

-- 只设置部分参数
gt.set_override({
    skip_centering = true
})
```

---

### gt.reset_override()

重置 Lua 覆盖态为默认值。

**参数：** 无

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 重置覆盖态
gt.reset_override()
```

---

## 主控热键 API

这些 API 用于控制主控热键和脚本执行状态。

### gt.register_hotkey(hotkey)

注册主控热键，用于开启/关闭脚本执行开关。

**参数：**
- `hotkey` (string): 热键名称（如 "f8", "alt", "ctrl+shift+f1"）

**返回值：**
- `success` (boolean): 是否成功
- `error` (string|nil): 错误信息

**示例：**
```lua
local ok, err = gt.register_hotkey("f8")
if ok then
    gt.log("主控热键已注册为 F8")
else
    gt.log("注册失败: " .. err)
end
```

---

### gt.enable_hotkey_right_click(enabled)

设置热键按下时是否执行右键相关操作（按下右键、锁定右键、移动鼠标到锁定位置）。

**参数：**
- `enabled` (boolean): 是否启用

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 启用右键模式
gt.enable_hotkey_right_click(true)

-- 禁用右键模式（只切换脚本开关）
gt.enable_hotkey_right_click(false)
```

---

### gt.is_hotkey_right_click_enabled()

获取热键右键开关状态。

**返回值：**
- `enabled` (boolean): 是否启用

**示例：**
```lua
if gt.is_hotkey_right_click_enabled() then
    gt.log("右键模式已启用")
else
    gt.log("右键模式已禁用")
end
```

---

### gt.toggle_scripts()

切换脚本开关状态（开→关 或 关→开）。

**返回值：**
- `enabled` (boolean): 切换后的状态

**示例：**
```lua
local enabled = gt.toggle_scripts()
if enabled then
    gt.log("脚本已启用")
else
    gt.log("脚本已禁用")
end
```

---

### gt.enable_scripts()

启用脚本执行。

**参数：** 无

**返回值：** 无

**示例：**
```lua
gt.enable_scripts()
gt.log("脚本已启用")
```

---

### gt.disable_scripts()

禁用脚本执行。

**参数：** 无

**返回值：** 无

**示例：**
```lua
gt.disable_scripts()
gt.log("脚本已禁用")
```

---

### gt.is_scripts_enabled()

检查脚本是否启用。

**返回值：**
- `enabled` (boolean): 是否启用

**示例：**
```lua
if gt.is_scripts_enabled() then
    gt.log("脚本当前已启用")
end
```

---

## 右键锁定 API

### gt.lock_right_click()

锁定右键（阻止右键被按下）。

**参数：** 无

**返回值：** 无

**示例：**
```lua
gt.lock_right_click()
gt.log("右键已锁定")
```

---

### gt.unlock_right_click()

解锁右键。

**参数：** 无

**返回值：** 无

**示例：**
```lua
gt.unlock_right_click()
gt.log("右键已解锁")
```

---

### gt.is_right_click_locked()

获取右键锁定状态。

**返回值：**
- `locked` (boolean): 是否锁定

**示例：**
```lua
if gt.is_right_click_locked() then
    gt.log("右键当前已锁定")
end
```

---

## 开关控制 API

### gt.enable_wasd_switch(enabled)

开启/关闭 WASD 开关。开启后，长按 WASD 超过 200ms 自动启用脚本。

**参数：**
- `enabled` (boolean): 是否启用

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
gt.enable_wasd_switch(true)
gt.log("WASD 开关已启用")
```

---

### gt.is_wasd_switch_enabled()

获取 WASD 开关状态。

**返回值：**
- `enabled` (boolean): 是否启用

---

### gt.enable_driver_key(enabled)

开启/关闭驱动级按键。

**参数：**
- `enabled` (boolean): 是否启用

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
gt.enable_driver_key(true)
gt.log("驱动级按键已启用")
```

---

### gt.is_driver_key_enabled()

获取驱动级按键状态。

**返回值：**
- `enabled` (boolean): 是否启用

---

## 手柄控制 API

### gt.get_gamepad_status()

获取手柄连接状态。

**返回值：**
- `status` (table): 手柄状态表，包含：
  - `connected` (boolean): 是否有手柄连接
  - `connected_count` (number): 连接的手柄数量
  - `message` (string): 状态消息

**示例：**
```lua
local status = gt.get_gamepad_status()
if status.connected then
    gt.log("已连接 " .. status.connected_count .. " 个手柄")
end
```

---

### gt.set_gamepad_vibration(enabled, intensity)

设置手柄震动。

**参数：**
- `enabled` (boolean): 是否启用震动
- `intensity` (number): 震动强度（0.0-1.0）

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 启用 80% 强度的震动
gt.set_gamepad_vibration(true, 0.8)

-- 禁用震动
gt.set_gamepad_vibration(false, 0)
```

---

### gt.set_gamepad_deadzone(deadzone, index)

设置手柄摇杆死区。

**参数：**
- `deadzone` (number): 死区值（0.0-1.0）
- `index` (number, 可选): 手柄索引（0-3），不提供则设置所有手柄

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 设置所有手柄死区为 0.24
gt.set_gamepad_deadzone(0.24)

-- 设置第一个手柄死区
gt.set_gamepad_deadzone(0.2, 0)
```

---

## 图像识别控制 API

### gt.start_image_recognition(config_ids)

启动图像识别。

**参数：**
- `config_ids` (table, 可选): 配置 ID 列表，不提供则启动所有已启用的配置

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 启动所有图像识别
gt.start_image_recognition()

-- 启动特定配置
gt.start_image_recognition({"config_1", "config_2"})
```

---

### gt.stop_image_recognition()

停止所有图像识别。

**返回值：**
- `success` (boolean): 是否成功

---

### gt.get_image_recognition_status()

获取图像识别状态。

**返回值：**
- `status` (table): 状态表，包含：
  - `running` (boolean): 是否正在运行

---

## 颜色识别控制 API

### gt.pick_color(x, y)

获取指定坐标的像素颜色。

**参数：**
- `x` (number): X 坐标
- `y` (number): Y 坐标

**返回值：**
- `r` (number): 红色分量
- `g` (number): 绿色分量
- `b` (number): 蓝色分量
- `hex` (string): 十六进制颜色值

**示例：**
```lua
local r, g, b, hex = gt.pick_color(100, 200)
gt.log(string.format("颜色: RGB(%d,%d,%d) = %s", r, g, b, hex))
```

---

### gt.get_color_recognition_status()

获取取色识别状态。

**返回值：**
- `status` (table): 状态表，包含：
  - `running` (boolean): 是否正在运行
  - `config_count` (number): 配置数量

---

## 屏幕与进程 API

### gt.get_screen_dpi(x, y)

获取屏幕 DPI 缩放信息。

**参数：**
- `x` (number, 可选): 屏幕坐标 X；传入后按该点所在显示器返回 DPI
- `y` (number, 可选): 屏幕坐标 Y；传入后按该点所在显示器返回 DPI

**返回值：**
- `scale` (number): 缩放比例（如 1.25）
- `scalePercent` (number): 缩放百分比（如 125）

**示例：**
```lua
local scale, percent = gt.get_screen_dpi()
gt.log(string.format("DPI 缩放: %.2f (%d%%)", scale, percent))

local screenW, screenH = gt.get_screen_size()
local pointScale, pointPercent = gt.get_screen_dpi(screenW / 2, screenH / 2)
gt.log(string.format("当前点 DPI 缩放: %.2f (%d%%)", pointScale, pointPercent))
```

---

### gt.set_excluded_processes(processes)

设置排除进程列表（这些进程中不触发脚本）。

**参数：**
- `processes` (table): 进程名称数组

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
gt.set_excluded_processes({"explorer.exe", "notepad.exe", "qq.exe"})
```

---

### gt.get_excluded_processes()

获取排除进程列表。

**返回值：**
- `processes` (table): 进程名称数组

---

## 录制功能 API

### gt.start_recording(use_real_delay, default_delay)

开始录制键盘和鼠标操作。

**参数：**
- `use_real_delay` (boolean, 可选): 是否使用真实延迟，默认 true
- `default_delay` (number, 可选): 默认延迟（毫秒），默认 100

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 使用真实延迟录制
gt.start_recording(true)

-- 使用固定延迟录制
gt.start_recording(false, 50)
```

---

### gt.stop_recording()

停止录制并返回录制的动作序列。

**返回值：**
- `actions` (table): 动作序列数组

**示例：**
```lua
local actions = gt.stop_recording()
gt.log("录制了 " .. #actions .. " 个动作")
for i, action in ipairs(actions) do
    gt.log(string.format("%d: %s", i, action.type))
end
```

---

### gt.get_recording_status()

获取录制状态。

**返回值：**
- `is_recording` (boolean): 是否正在录制
- `count` (number): 已录制的动作数量

---

### gt.clear_recording()

清空录制的动作列表。

**返回值：**
- `success` (boolean): 是否成功

---

## 动作注册 API

### gt.register_hotkey_actions(hotkey, actions, execution_mode, loop_count, loop_duration_seconds, random_delay_enabled, random_delay_min, random_delay_max)

注册热键动作序列（通过 HTTP API）。

**参数：**
- `hotkey` (string): 热键名称
- `actions` (table): 动作序列数组
- `execution_mode` (string, 可选): 执行模式，可选 "once"、"loop"、"hold"

**返回值：**
- `success` (boolean): 是否成功
- `error` (string|nil): 错误信息

**示例：**
```lua
local actions = {
    {type = "key", key = "1", action = "down"},
    {type = "delay", value = 50},
    {type = "key", key = "1", action = "up"}
}

local ok, err = gt.register_hotkey_actions("f1", actions, "once")
if ok then
    gt.log("动作序列已注册到 F1")
end
```

**循环模式示例：**
```lua
local actions = {
    { type = "mouse", buttonName = "left", action = "down" },
    { type = "delay", value = 40 },
    { type = "mouse", buttonName = "left", action = "up" }
}

local ok, err = gt.register_hotkey_actions(
    "xbutton1",
    actions,
    "loop",
    0,
    0,
    true,
    30,
    80
)

if not ok then
    gt.log("注册失败: " .. tostring(err))
end
```

---

## 定时任务中心 API

这组 API 对应“定时任务中心”的真实任务数据。

### gt.list_timer_tasks()

列出当前定时任务中心里的任务。

**返回值：**
- `tasks` (table)
- `error` (string|nil)

**每个任务常见字段：**
- `id` (string)
- `name` (string)
- `type` (string)
- `scheduleMode` (string): `clock` / `interval`
- `time` (string)
- `intervalValue` (number)
- `intervalUnit` (string)
- `enabled` (boolean)
- `repeat` (string)
- `repeatDays` (table)
- `config` (table)
- `lastRun` (string|nil)

**示例：**
```lua
local tasks, err = gt.list_timer_tasks()
if err then
  gt.log("读取定时任务失败: " .. tostring(err))
  return
end

for _, task in ipairs(tasks) do
  gt.log(string.format(
    "%s | type=%s | mode=%s | enabled=%s",
    tostring(task.name),
    tostring(task.type),
    tostring(task.scheduleMode),
    tostring(task.enabled)
  ))
end
```

### gt.save_timer_task(task)

创建或更新定时任务。

**参数：**
- `task` (table): 任务对象

**任务字段：**
- `id` (string): 任务唯一 ID
- `name` (string): 任务名称
- `type` (string): `reminder` / `open_app` / `shutdown` / `voice` / `device_binding`
- `schedule_mode` (string): `clock` / `interval`
- `time` (string): 固定时间模式使用，格式 `HH:MM`
- `interval_value` (number): 间隔模式使用的数值
- `interval_unit` (string): `ms` / `second` / `minute` / `hour`
- `enabled` (boolean): 是否启用
- `repeat` (string): `once` / `hourly` / `daily` / `weekly`
- `repeatDays` (table, 可选): 每周重复时使用，范围 `0-6`
- `config` (table): 任务配置

**config 字段说明：**
- `type = "reminder"`
  - `message` (string): 提醒内容
- `type = "open_app"`
  - `appPath` (string): 程序路径
- `type = "shutdown"`
  - `shutdownDelay` (number): 关机延迟秒数
- `type = "voice"`
  - `voiceText` (string): 播报内容
- `type = "device_binding"`
  - `binding_kind` (string): `keyboard` / `mouse` / `gamepad`
  - `binding_target` (string): 设备动作目标名

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：固定时间提醒**
```lua
local ok, err = gt.save_timer_task({
  id = "daily_remind_0900",
  name = "九点提醒",
  type = "reminder",
  schedule_mode = "clock",
  time = "09:00",
  enabled = true,
  repeat = "daily",
  config = {
    message = "该开始处理日常任务了"
  }
})

if not ok then
  gt.log("保存任务失败: " .. tostring(err))
end
```

**示例：间隔执行设备动作**
```lua
local ok, err = gt.save_timer_task({
  id = "auto_cast_q",
  name = "每 5 秒执行主技能",
  type = "device_binding",
  schedule_mode = "interval",
  interval_value = 5,
  interval_unit = "second",
  time = "00:00",
  enabled = true,
  repeat = "daily",
  config = {
    binding_kind = "keyboard",
    binding_target = "key_q"
  }
})

if not ok then
  gt.log("保存设备动作任务失败: " .. tostring(err))
end
```

### gt.delete_timer_task(task_id)

删除指定定时任务。

**参数：**
- `task_id` (string): 任务 ID

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
gt.delete_timer_task("auto_cast_q")
```

### gt.execute_timer_task(task_id)

立即执行指定定时任务。

**参数：**
- `task_id` (string): 任务 ID

**返回值：**
- `success` (boolean)
- `error` (string|nil)

**示例：**
```lua
local ok, err = gt.execute_timer_task("daily_remind_0900")
if not ok then
  gt.log("立即执行任务失败: " .. tostring(err))
end
```

---

### gt.unregister_hotkey_script(hotkey)

注销热键脚本。

**参数：**
- `hotkey` (string): 热键名称

**返回值：**
- `success` (boolean): 是否成功

---

### gt.set_mouse_skill_interval(button, interval)

设置鼠标技能循环间隔。

**参数：**
- `button` (string): 鼠标按钮（"lbutton" 或 "rbutton"）
- `interval` (number): 循环间隔（毫秒）

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 设置左键循环间隔为 50ms
gt.set_mouse_skill_interval("lbutton", 50)
```

---

## 准星覆盖层 API

准星覆盖层是一个显示在屏幕中心的透明窗口，可以显示各种样式的准星或圆点。窗口完全穿透鼠标，不会影响游戏操作。

### gt.crosshair_show()

显示准星覆盖层。

**参数：** 无

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
gt.crosshair_show()
gt.log("准星已显示")
```

---

### gt.crosshair_hide()

隐藏准星覆盖层。

**参数：** 无

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
gt.crosshair_hide()
gt.log("准星已隐藏")
```

---

### gt.crosshair_toggle()

切换准星显示状态。

**参数：** 无

**返回值：**
- `visible` (boolean): 切换后的状态（true=显示，false=隐藏）

**示例：**
```lua
local visible = gt.crosshair_toggle()
if visible then
    gt.log("准星已显示")
else
    gt.log("准星已隐藏")
end
```

---

### gt.crosshair_config(type, color, size, thickness)

一次性设置多个准星配置参数。

**参数：**
- `type` (string, 可选): 准星类型
  - `"dot"`: 圆点
  - `"cross"`: 十字准星
  - `"cross-gap"`: 带间隙的十字准星（默认）
  - `"circle"`: 圆环
- `color` (string, 可选): 颜色（十六进制，如 `"#ff0000"`）
- `size` (number, 可选): 大小（1-200）
- `thickness` (number, 可选): 线条粗细（1-20）

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 设置红色十字准星，大小 30
gt.crosshair_config("cross", "#ff0000", 30, 2)

-- 设置绿色圆点，大小 8
gt.crosshair_config("dot", "#00ff00", 8)
```

---

### gt.crosshair_get_config()

获取当前准星配置。

**参数：** 无

**返回值：**
- `type` (string): 准星类型
- `color` (string): 颜色
- `size` (number): 大小
- `visible` (boolean): 是否可见

**示例：**
```lua
local crosshair_type, color, size, visible = gt.crosshair_get_config()
gt.log(string.format("类型: %s, 颜色: %s, 大小: %d, 可见: %s", 
    crosshair_type, color, size, tostring(visible)))
```

---

### gt.crosshair_type(type)

设置准星类型。

**参数：**
- `type` (string): 准星类型
  - `"dot"`: 圆点
  - `"cross"`: 十字准星
  - `"cross-gap"`: 带间隙的十字准星（带中心点）
  - `"circle"`: 圆环

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 切换到圆点模式
gt.crosshair_type("dot")

-- 切换到十字准星
gt.crosshair_type("cross")
```

---

### gt.crosshair_color(color)

设置准星颜色。

**参数：**
- `color` (string): 十六进制颜色值

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 红色
gt.crosshair_color("#ff0000")

-- 绿色
gt.crosshair_color("#00ff00")

-- 青色
gt.crosshair_color("#00ffff")
```

---

### gt.crosshair_size(size)

设置准星大小。

**参数：**
- `size` (number): 准星大小（1-200 像素）

**返回值：**
- `success` (boolean): 是否成功

**示例：**
```lua
-- 小准星
gt.crosshair_size(10)

-- 中等准星
gt.crosshair_size(25)

-- 大准星
gt.crosshair_size(50)
```

---

### gt.crosshair_offset(x, y)

设置准星相对屏幕中心的位置偏移。

**参数：**
- `x` (number): 水平偏移，正数向右，负数向左
- `y` (number): 垂直偏移，正数向下，负数向上

**返回值：**
- `success` (boolean): 是否成功

**示例 1：向右偏移**
```lua
gt.crosshair_offset(80, 0)
```

**示例 2：向上偏移**
```lua
gt.crosshair_offset(0, -40)
```

**示例 3：恢复居中**
```lua
gt.crosshair_offset(0, 0)
```

---

### gt.crosshair_fixed(enabled)

设置准星是否固定在偏移位置。

**参数：**
- `enabled` (boolean|number): `true/1` 开启，`false/0` 关闭

**返回值：**
- `success` (boolean): 是否成功

**示例 1：开启固定模式**
```lua
gt.crosshair_fixed(true)
```

**示例 2：关闭固定模式**
```lua
gt.crosshair_fixed(false)
```

**示例 3：配合偏移一起使用**
```lua
gt.crosshair_offset(120, -20)
gt.crosshair_fixed(true)
```

---

### 准星使用示例

```lua
-- 准星控制脚本示例

-- 启动时显示准星
gt.crosshair_show()
gt.crosshair_config("cross-gap", "#00ff00", 20, 2)
gt.log("准星已初始化")

-- 按 F1 切换准星显示
function toggle_crosshair()
    local visible = gt.crosshair_toggle()
    gt.log("准星: " .. (visible and "显示" or "隐藏"))
end
gt.bind_hotkey("f1", "toggle_crosshair")

-- 按 F2 切换准星类型
local crosshair_types = {"dot", "cross", "cross-gap", "circle"}
local current_type_index = 3

function cycle_crosshair_type()
    current_type_index = (current_type_index % #crosshair_types) + 1
    local new_type = crosshair_types[current_type_index]
    gt.crosshair_type(new_type)
    gt.log("准星类型: " .. new_type)
end
gt.bind_hotkey("f2", "cycle_crosshair_type")

-- 按 F3 变红色（瞄准敌人时）
function crosshair_red()
    gt.crosshair_color("#ff0000")
end
gt.bind_hotkey("f3", "crosshair_red")

-- 按 F4 变绿色（默认）
function crosshair_green()
    gt.crosshair_color("#00ff00")
end
gt.bind_hotkey("f4", "crosshair_green")

gt.log("准星控制脚本已加载")
gt.log("F1: 切换显示, F2: 切换类型, F3: 红色, F4: 绿色")
```

---

### 准星跟随脚本开关示例

```lua
-- 准星跟随脚本开关示例
-- 开启脚本时显示准星，关闭时隐藏
-- 每次显示随机颜色和形状

-- 可选颜色列表
local colors = {
    "#ff0000",  -- 红色
    "#00ff00",  -- 绿色
    "#00ffff",  -- 青色
    "#ffff00",  -- 黄色
    "#ff00ff",  -- 品红
    "#ffffff",  -- 白色
    "#ff6600",  -- 橙色
    "#00ff99",  -- 青绿
}

-- 可选形状列表
local shapes = {
    "dot",        -- 实心圆点
    "cross",      -- 十字准星
    "cross-gap",  -- 带间隙十字
    "circle",     -- 圆环
}

-- 随机选择颜色
function random_color()
    local index = math.random(1, #colors)
    return colors[index]
end

-- 随机选择形状
function random_shape()
    local index = math.random(1, #shapes)
    return shapes[index]
end

-- 初始化随机种子
math.randomseed(os.time())

-- 配置准星大小
gt.crosshair_size(20)

-- 上一次的脚本状态
local last_enabled = false

-- 监控脚本状态
function check_script_status()
    while true do
        local enabled = gt.is_scripts_enabled()
        
        -- 状态发生变化
        if enabled ~= last_enabled then
            if enabled then
                -- 脚本开启：显示准星，随机颜色和形状
                local color = random_color()
                local shape = random_shape()
                gt.crosshair_type(shape)
                gt.crosshair_color(color)
                gt.crosshair_show()
                gt.log("准星已显示，形状: " .. shape .. "，颜色: " .. color)
            else
                -- 脚本关闭：隐藏准星
                gt.crosshair_hide()
                gt.log("准星已隐藏")
            end
            last_enabled = enabled
        end
        
        gt.sleep(50)  -- 50ms 检测一次
    end
end

gt.log("=== 准星跟随脚本 ===")
gt.log("按主控热键开启脚本时显示随机颜色和形状的准星")
gt.log("关闭脚本时隐藏准星")

-- 启动监控
check_script_status()
```

---

## 示例脚本

### 自动连点器（按住模式）

```lua
-- 自动连点器（按住 F1 时连点）
gt.log("自动连点器已启动")
gt.log("按住 F1 开始连点，松开 F1 停止")

while true do
    if gt.is_key_pressed("f1") then
        gt.click("left")
        gt.sleep_random(30, 50)
    else
        gt.sleep(10)  -- 空闲时降低 CPU 占用
    end
end
```

---

### 自动连点器（Toggle 模式）

```lua
-- 自动连点器（按一次 F1 开始，再按一次 F1 停止）
function auto_click()
    gt.click("left")
end

-- 绑定热键循环，间隔 50ms
gt.bind_hotkey_loop("f1", "auto_click", 50)

gt.log("自动连点器 Toggle 版")
gt.log("按 F1 开始/停止自动连点")
```

---

### 多功能热键宏

```lua
-- 多功能热键示例
-- F1: 自动连点
-- F2: 自动按键 1-2-3
-- F3: 停止所有

function click_loop()
    gt.click("left")
end

function key_combo_loop()
    gt.key("1")
    gt.sleep(100)
    gt.key("2")
    gt.sleep(100)
    gt.key("3")
end

function stop_all()
    gt.stop_all_loops()
    gt.log("所有循环已停止")
end

-- 注册热键
gt.bind_hotkey_loop("f1", "click_loop", 50)
gt.bind_hotkey_loop("f2", "key_combo_loop", 500)
gt.bind_hotkey("f3", "stop_all")

gt.log("多功能热键宏已加载")
gt.log("F1: 自动连点 (Toggle)")
gt.log("F2: 自动按键 1-2-3 (Toggle)")
gt.log("F3: 停止所有")
```

---

### 带状态显示的连点器

```lua
-- 带状态显示的连点器
local click_count = 0

function counting_click()
    gt.click("left")
    click_count = click_count + 1
    -- 每 10 次点击显示一次
    if click_count % 10 == 0 then
        gt.log("已点击: " .. click_count .. " 次")
    end
end

function show_status()
    if gt.is_loop_running("f1") then
        gt.log("状态: 运行中, 总点击: " .. click_count)
    else
        gt.log("状态: 已停止, 总点击: " .. click_count)
    end
end

function reset_counter()
    click_count = 0
    gt.log("计数器已重置")
end

gt.bind_hotkey_loop("f1", "counting_click", 50)
gt.bind_hotkey("f2", "show_status")
gt.bind_hotkey("f3", "reset_counter")

gt.log("带计数的连点器")
gt.log("F1: 开始/停止连点")
gt.log("F2: 显示状态")
gt.log("F3: 重置计数器")
```

---

### Apex 压枪脚本

```lua
-- Apex Legends 压枪脚本示例
-- 注意：仅供学习参考

-- R301 压枪数据
local r301_pattern = {
    {x = 0, y = 3},
    {x = 1, y = 2},
    {x = -1, y = 2},
    {x = 0, y = 3},
    {x = 1, y = 2},
    -- ... 更多数据
}

-- 设置灵敏度
gt.set_apex_config(1.0, 1.0)
local modifier = gt.get_apex_modifier()

function recoil_control()
    for i, p in ipairs(r301_pattern) do
        if not gt.is_key_pressed("lbutton") then
            break
        end
        
        local x = math.floor(p.x * modifier)
        local y = math.floor(p.y * modifier)
        
        gt.driver_mouse_move_relative(x, y)
        gt.sleep(6.6)
    end
end

gt.log("压枪脚本已加载")
gt.bind_hotkey("lbutton", "recoil_control")
```

---

### 颜色检测自动操作

```lua
-- 检测技能冷却完成后自动施放
-- 假设技能图标在 (100, 500)，冷却完成时为绿色

local skill_pos = {x = 100, y = 500}
local ready_color = {r = 0, g = 200, b = 0}

function check_skill()
    while true do
        if gt.check_color(
            skill_pos.x, skill_pos.y,
            ready_color.r, ready_color.g, ready_color.b,
            30  -- 容差
        ) then
            gt.key_press("1")  -- 按技能键
            gt.sleep(500)  -- 等待冷却
        end
        
        gt.sleep(100)  -- 检测间隔
    end
end

gt.log("技能检测已启动")
check_skill()
```

---

### 自动截图工具

```lua
-- 每隔 5 秒截取屏幕中央区域

local interval = 5000  -- 5 秒
local count = 0
local max_count = 10

local w, h = gt.get_screen_size()
local region = {
    x = w / 4,
    y = h / 4,
    width = w / 2,
    height = h / 2
}

while count < max_count do
    count = count + 1
    local filename = string.format("C:/screenshots/capture_%03d.png", count)
    
    local ok, err = gt.screenshot(
        region.x, region.y,
        region.width, region.height,
        filename
    )
    
    if ok then
        gt.log(string.format("截图 %d/%d: %s", count, max_count, filename))
    else
        gt.log("截图失败: " .. err)
    end
    
    gt.sleep(interval)
end

gt.log("截图任务完成！")
```

---

### 鼠标锁定位置偏移示例

```lua
-- 鼠标锁定位置偏移示例
-- 适用于某些游戏需要将视角锁定在偏离中心的位置

-- 设置锁定位置向上偏移 50 像素（适合某些俯视角游戏）
gt.set_lock_offset(0, -50)
gt.log("锁定位置已设置为屏幕中心上方 50 像素")

-- 根据游戏模式动态调整
function set_mode_fps()
    -- FPS 模式：锁定在屏幕中心
    gt.reset_lock_offset()
    gt.log("FPS 模式：锁定在屏幕中心")
end

function set_mode_moba()
    -- MOBA 模式：锁定在屏幕中心偏上
    gt.set_lock_offset(0, -100)
    gt.log("MOBA 模式：锁定在中心上方 100 像素")
end

function set_mode_custom()
    -- 自定义模式：右下偏移
    gt.set_lock_offset(200, 150)
    gt.log("自定义模式：右下偏移 (200, 150)")
end

-- 绑定热键切换模式
gt.bind_hotkey("f9", "set_mode_fps")
gt.bind_hotkey("f10", "set_mode_moba")
gt.bind_hotkey("f11", "set_mode_custom")

-- 显示当前偏移
function show_offset()
    local x, y = gt.get_lock_offset()
    gt.log(string.format("当前锁定偏移: (%d, %d)", x, y))
    gt.reminder(string.format("锁定偏移: (%d, %d)", x, y), 2000)
end

gt.bind_hotkey("f12", "show_offset")

gt.log("鼠标锁定偏移脚本已加载")
gt.log("F9: FPS 模式（中心）")
gt.log("F10: MOBA 模式（上偏移）")
gt.log("F11: 自定义模式")
gt.log("F12: 显示当前偏移")
```

---

### 完整的主控热键配置示例

```lua
-- 完整的主控热键配置示例
-- 演示如何通过 Lua 完全控制热键系统

-- 1. 注册主控热键
local ok, err = gt.register_hotkey("f8")
if not ok then
    gt.log("注册主控热键失败: " .. err)
    return
end
gt.log("主控热键已注册为 F8")

-- 2. 配置右键模式
gt.enable_hotkey_right_click(true)  -- 启用右键锁定功能
gt.log("右键模式已启用")

-- 3. 设置锁定位置偏移
gt.set_lock_offset(0, -30)  -- 向上偏移 30 像素
gt.log("锁定位置已设置")

-- 4. 启用驱动级按键
gt.enable_driver_key(true)
gt.log("驱动级按键已启用")

-- 5. 配置 WASD 开关
gt.enable_wasd_switch(true)
gt.log("WASD 开关已启用")

-- 6. 设置排除进程
gt.set_excluded_processes({
    "explorer.exe",
    "notepad.exe",
    "qq.exe",
    "wechat.exe"
})
gt.log("排除进程已设置")

-- 7. 注册一些动作
local actions = {
    {type = "key", key = "1", action = "down"},
    {type = "delay", value = 50},
    {type = "key", key = "1", action = "up"}
}
gt.register_hotkey_actions("lbutton", actions, "once")
gt.log("左键动作已注册")

-- 8. 设置鼠标技能循环间隔
gt.set_mouse_skill_interval("lbutton", 80)
gt.log("左键循环间隔已设置为 80ms")

gt.log("=== 配置完成 ===")
gt.log("按 F8 开启/关闭脚本")
gt.log("长按 WASD 也可开启脚本")
```


## 更新日志

### v1.2.0
- 新增准星覆盖层 API：`gt.crosshair_show()`, `gt.crosshair_hide()`, `gt.crosshair_toggle()`
- 新增准星配置 API：`gt.crosshair_config()`, `gt.crosshair_get_config()`, `gt.crosshair_type()`, `gt.crosshair_color()`, `gt.crosshair_size()`
- 支持四种准星样式：圆点 (dot)、十字 (cross)、带间隙十字 (cross-gap)、圆环 (circle)

### v1.1.0
- 新增鼠标锁定位置偏移 API：`gt.set_lock_offset()`, `gt.get_lock_offset()`, `gt.reset_lock_offset()`
- 新增主控热键 API：`gt.register_hotkey()`, `gt.enable_hotkey_right_click()`, `gt.toggle_scripts()` 等
- 新增右键锁定 API：`gt.lock_right_click()`, `gt.unlock_right_click()`, `gt.is_right_click_locked()`
- 新增开关控制 API：`gt.enable_wasd_switch()`, `gt.enable_driver_key()` 等
- 新增手柄控制 API：`gt.get_gamepad_status()`, `gt.set_gamepad_vibration()`, `gt.set_gamepad_deadzone()`
- 新增图像识别控制 API：`gt.start_image_recognition()`, `gt.stop_image_recognition()`
- 新增颜色识别控制 API：`gt.pick_color()`, `gt.get_color_recognition_status()`
- 新增屏幕与进程 API：`gt.get_screen_dpi()`, `gt.set_excluded_processes()`
- 新增录制功能 API：`gt.start_recording()`, `gt.stop_recording()`
- 新增动作注册 API：`gt.register_hotkey_actions()`, `gt.unregister_hotkey_script()`

### v1.0.0
- 初始版本
- 支持鼠标、键盘、驱动级操作
- 支持热键绑定
- 支持取色识别
- 支持截图功能
- 支持基础图像识别

