DSL 脚本语法手册
VB风格语法 · 大小写不敏感 · 双向转译(DSL ↔ JSON) · AI智能识别 · 每个指令含正确示例 / 错误示例 / 避坑指南
v214.3.19
41种动作类型
⚠️ 常见错误速查
以下是使用 DSL 时最容易踩的坑,正式学习前先浏览一遍可少走弯路:
❌ If x > 1 And y > 2 Then
✅ 嵌套If:If x > 1 Then → If y > 2 Then
条件表达式不支持 And/Or/Not 逻辑运算符,需用嵌套If实现
❌ Return
✅ 用 Goto 跳到 End Sub 前(或直接让 Sub 执行到 EndSub)
不存在 Return 命令,子程序执行到 EndSub 自动返回
❌ Call sub(1, 2, key=3)
✅ 纯位置 Call sub(1, 2) 或纯命名 Call sub(key1=1, key2=2)
不支持混合参数,位置参数和命名参数不可混用
❌ Sub name(x=10)
✅ Sub name(x)
不支持默认参数值,参数列表只写参数名
❌ SetGlobal count = 0(普通计数器)
✅ Set count = 0(只有跨任务才用 SetGlobal)
SetGlobal 用于跨任务持久化,普通变量用 Set 即可
❌ GetTime 返回 HH:mm:ss
✅ GetTime 返回 yyMMddHHmmss(如 260623143052)
GetTime 返回14位时间戳格式,非 HH:mm:ss
❌ OCR x_var, y_var, w, h -> text
✅ OCR 100, 200, 300, 400 -> text(从(100,200)到(300,400))
OCR 坐标参数只支持纯数字,不支持变量
❌ Set 变量名 = 10
✅ Set var_name = 10
变量名只支持ASCII字符(字母/数字/下划线)
❌ End(裸结束标记)
✅ End If / End While / End Repeat
避免歧义,应使用完整的结束标记
❌ Start script_id
✅ Start "script_id"
脚本ID必须加引号,为字符串类型
❌ AISmartClick "按钮" -> pos
✅ AISmartClick "按钮"(如需坐标请用 AIFindElement)
AISmartClick 不支持结果变量,如需获取坐标请改用 AIFindElement
❌ While True
✅ While count < 1000
While True 永远为真,1000次后强制退出;应使用有界条件
❌ Sleep 2000ms
✅ Sleep 2000
不支持 ms 后缀,参数直接写毫秒数值
❌ Set lou = lou - 1(减号两侧有空格)
✅ Set lou = $lou-1(减号两侧不加空格)
减法运算符两侧空格会导致算术解析失败,变量值被当作字符串拼接
📋 1. 基础规则
| 规则 | 说明 |
| 大小写 | 不敏感,click / Click / CLICK 均等效 |
| 注释 | ' 单引号 或 # 井号开头的行为注释行;行尾注释同样支持 |
| 空行 | 自动忽略 |
| 缩进 | 块内语句使用空格缩进(非强制,但强烈推荐用于可读性) |
| 字符串 | 双引号 "..." 或单引号 '...' 包裹 |
| 变量引用 | 直接使用变量名,如 count、color_result |
| 变量定义 | Set var = value,$ 前缀可选;也可通过 GetColor/FindColor/FindImage/CheckApp/IsColor 等 -> 箭头语法定义 |
| 关键字 | If Then Else End If While End While Repeat End Repeat Sub EndSub Label Goto |
✅ 正确示例
' 这是单行注释
# 这也是单行注释
Click 100, 200 ' 行尾注释
Click 100, 200 # 行尾注释也可以
❌ 错误示例
❌ // 这是注释(双斜杠)
✅ ' 这是注释 或 # 这是注释
DSL 不支持 C 风格的 // 或 /* */ 注释,只支持单引号和井号
⚠️ 避坑指南
单引号 ' 既是注释符号也是字符串包裹符。当单引号出现在行首或参数分隔符后,解析为注释;出现在参数位置则解析为字符串。为避免歧义,推荐字符串统一使用双引号,注释使用单引号或井号。
👆 2. 触控操作
2.1 Click — 点击
Click x, y
| 参数 | 类型 | 必填 | 说明 |
| x | number/var | ✅ | 目标 X 坐标(像素) |
| y | number/var | ✅ | 目标 Y 坐标(像素) |
✅ 正确示例
Click 100, 200
Click target_x, target_y
❌ 错误示例
❌ Click (100, 200)
✅ Click 100, 200
不支持括号包裹坐标,参数之间用逗号分隔即可
❌ 错误示例
❌ Click 100 200
✅ Click 100, 200
缺少逗号分隔符,解析器无法识别两个参数
⚠️ 避坑指南
坐标值不能超出屏幕分辨率。常见手机分辨率 1080×1920,点击坐标 x < 0 或 x > 1080 不会报错但点击无效。建议先用 GetColor 确认目标位置。变量引用坐标时需确保变量已被赋值,未定义的变量会被当作空字符串导致解析失败。
2.2 LongClick — 长按
LongClick x, y
| 参数 | 类型 | 必填 | 说明 |
| x | number/var | ✅ | 目标 X 坐标 |
| y | number/var | ✅ | 目标 Y 坐标 |
| duration | number/var | 否 | 长按持续时间(ms),默认 1000 |
✅ 正确示例
LongClick 500, 800
LongClick 500, 800, 2000 ' 长按2秒
❌ 错误示例
❌ LongClick 500, 800, 2s
✅ LongClick 500, 800, 2000
不支持时间后缀(s/ms),duration 参数直接写毫秒数值
⚠️ 避坑指南
duration 默认值 1000ms(1秒)。不同应用对长按的响应时间不同:部分应用 500ms 即触发,有些需要 1500ms 以上。如果长按没反应,尝试增大 duration。duration 过长(超过5000ms)可能触发系统的长按强制关闭菜单。
2.3 Swipe — 滑动
Swipe x1, y1, x2, y2
| 参数 | 类型 | 必填 | 说明 |
| x1, y1 | number/var | ✅ | 起始坐标 |
| x2, y2 | number/var | ✅ | 终点坐标 |
| duration | number/var | 否 | 滑动持续时间(ms),默认 500 |
✅ 正确示例
Swipe 540, 1500, 540, 500 ' 向上滑动(从下到上)
Swipe 540, 500, 540, 1500, 300 ' 向下滑动,快速300ms
Swipe 100, 960, 900, 960, 800 ' 向右滑动
❌ 错误示例
❌ Swipe 540, 1500, 540, 500, 0.3s
✅ Swipe 540, 1500, 540, 500, 300
不支持秒后缀,duration 直接写毫秒数值
⚠️ 避坑指南
滑动方向由起止坐标决定:y1 > y2 为向上滑(看下方内容),y1 < y2 为向下滑。duration 太短(<100ms)会被系统当作快速点击而非滑动;太长(>2000ms)会变成拖拽而非惯性滑动。推荐范围 300-800ms。起止坐标的 x 值建议保持一致(垂直滑动)或 y 值一致(水平滑动),斜向滑动在部分应用中可能不触发翻页。
⌨️ 3. 文本输入
3.1 InputText — 输入文本
InputText "文本内容"
| 参数 | 类型 | 必填 | 说明 |
| text | string/var | ✅ | 要输入的文本,支持变量引用 |
✅ 正确示例
InputText "hello world"
InputText "你好世界"
InputText username ' 输入变量username的值
InputText "等级: " + level ' 字符串拼接
❌ 错误示例
❌ InputText hello(想输入字符串hello)
✅ InputText "hello"
不加引号的 hello 会被当作变量引用。若变量 hello 未定义则输入空字符串
⚠️ 避坑指南
输入前必须确保焦点已在输入框上(先 Click 点击输入框再 InputText)。中文输入依赖设备的输入法支持,部分定制ROM可能无法输入中文。输入长文本时建议分段输入并加 Sleep 间隔。输入密码等敏感信息时注意 Log 不要打印明文。
⏱️ 4. 等待
4.1 Sleep — 等待
Sleep duration
| 参数 | 类型 | 必填 | 说明 |
| duration | number/var | ✅ | 等待时间,单位毫秒(ms) |
✅ 正确示例
Sleep 1000 ' 等待 1 秒
Sleep 500 ' 等待 0.5 秒
Sleep delay_ms ' 使用变量
❌ 错误示例
❌ Sleep 2000ms
✅ Sleep 2000
不支持 ms 后缀,参数直接写毫秒数值
❌ 错误示例
❌ Sleep 2(想等待2秒)
✅ Sleep 2000
参数单位是毫秒不是秒,Sleep 2 只等2毫秒
⚠️ 避坑指南
Sleep 是阻塞式等待,期间脚本完全暂停。不要用超长 Sleep(如 Sleep 60000 等1分钟)替代定时任务,应使用 WaitUntil。网络加载等待建议用 AISmartWait 智能轮询代替固定 Sleep,避免等待过长浪费时间或等待过短导致后续操作失败。
🔘 5. 按键操作
5.1 PressBack — 返回键
PressBack
无参数,模拟按下 Android 返回键。
❌ 错误示例
❌ PressBack 1
✅ PressBack
PressBack 不接受任何参数,按一次返回即可
⚠️ 避坑指南
连续多次 PressBack 可能退出应用回到桌面。如果需要返回多次,建议每次之间加 Sleep 500 等待界面切换。部分应用会拦截返回键弹出退出确认弹窗,需配合 AICheck 检测弹窗。
5.2 PressHome — Home 键
PressHome
无参数,模拟按下 Android Home 键,回到桌面。
❌ 错误示例
❌ PressHome()
✅ PressHome
不是函数调用,无需括号,直接写关键字即可
⚠️ 避坑指南
PressHome 会立即回到桌面,当前应用转入后台。部分设备按下 Home 会打开负一屏而非桌面,需根据设备调整。脚本结束前调用 PressHome 可确保设备回到干净状态。
📝 6. 日志输出
6.1 Log — 输出日志
Log "消息内容"
| 参数 | 类型 | 必填 | 说明 |
| message | string/var | ✅ | 日志消息,支持变量引用和字符串拼接 |
✅ 正确示例
Log "开始执行任务"
Log "当前颜色: color_value"
Log "坐标: (" + x + ", " + y + ")"
Log status ' 直接输出变量值
❌ 错误示例
❌ Log 当前状态(想输出字面文本)
✅ Log "当前状态"
不加引号会被当作变量引用,变量未定义则输出空内容
⚠️ 避坑指南
Log 输出的内容会显示在 B 端日志面板。不要在循环中高频 Log(如 Repeat 1000 内每次都 Log),会导致日志面板卡顿和日志缓冲区溢出。输出变量值时,对象类型变量(如 FindColor 的结果 {x, y})需用 pos.x 和 pos.y 分别输出。输出中文需确保编码正确。
🎨 7. 颜色操作
7.1 GetColor — 获取像素颜色
GetColor x, y var
| 参数 | 类型 | 必填 | 说明 |
| x | number/var | ✅ | 像素 X 坐标 |
| y | number/var | ✅ | 像素 Y 坐标 |
| var | 变量名 | ✅ | 颜色值 (#RRGGBB格式) 存入该变量(不含 $ 前缀) |
✅ 正确示例
GetColor 100, 200 -> pixel_color
Log "像素颜色: pixel_color"
' 获取颜色后用~=模糊匹配判断
GetColor 540, 960 -> center_color
If center_color ~= "#346BB8" Then
Log "颜色匹配"
End If
❌ 错误示例
❌ GetColor 100, 200
✅ GetColor 100, 200 -> pixel_color
GetColor 必须用 -> 指定结果变量,否则获取的颜色无处存储
⚠️ 避坑指南
返回值格式固定为 #RRGGBB(如 #FF0000),不含 alpha 通道。屏幕处于动态画面(动画/视频)时取色可能不稳定,建议配合 Sleep 等画面静止后再取色。不同设备屏幕色域不同,同一位置同一画面的颜色值可能略有差异,推荐用 ~= 模糊匹配而非 == 精确匹配。
7.2 IsColor — 判断颜色
支持两种写法:简单形(结果存变量)和 块形(Then/Else 分支直接执行)。
简单形
IsColor x, y, "color" var
| 参数 | 类型 | 必填 | 说明 |
| x | number/var | ✅ | 像素 X 坐标 |
| y | number/var | ✅ | 像素 Y 坐标 |
| color | string | ✅ | 目标颜色 (#RRGGBB 格式) |
| threshold | number | 否 | 色差阈值,默认 10 |
| var | 变量名 | ✅ | 判断结果 (true/false) 存入该变量 |
块形(Then/Else 分支)v156
IsColor x, y, "color" Then
语句块(颜色匹配时执行)
Else
语句块(颜色不匹配时执行)
End IsColor
✅ 正确示例
' 简单形:结果存变量
IsColor 12, 12, "#FFFFFF", 10 -> color_match
If color_match == True Then
Click 100, 200
End If
' 块形:直接分支(更简洁)
IsColor 540, 960, "#FF0000", 15 Then
Click 540, 960
Log "点击红色区域"
Else
Log "颜色不匹配"
End IsColor
❌ 错误示例
❌ IsColor 540, 960, FF0000, 10 -> match
✅ IsColor 540, 960, "#FF0000", 10 -> match
颜色值必须加引号且带 # 前缀,格式为 "#RRGGBB"
⚠️ 避坑指南
threshold(色差阈值)表示允许的颜色偏差范围,默认 10。threshold 越大越宽松(容易匹配),越小越严格。游戏画面颜色常因渲染波动有 ±5 左右偏差,建议 threshold 设 10-20。threshold 设 0 表示精确匹配,几乎只在静态截图场景可用。块形语法的 End IsColor 不可简写为 End(会产生歧义)。
7.3 FindColor — 区域找色
FindColor x, y, width, height, "color" var
| 参数 | 类型 | 必填 | 说明 |
| x, y | number/var | ✅ | 搜索区域左上角坐标 |
| width, height | number/var | ✅ | 搜索区域宽高(像素) |
| color | string | ✅ | 目标颜色 (#RRGGBB) |
| threshold | number | 否 | 色差阈值,默认 10 |
| var | 变量名 | ✅ | 找到的坐标,存储为 {x, y} 对象;未找到则为空字符串 |
✅ 正确示例
FindColor 0, 0, 1080, 1920, "#FF0000", 20 -> found_pos
If found_pos != "" Then
Click found_pos.x, found_pos.y
Else
Log "未找到目标颜色"
End If
❌ 错误示例
❌ FindColor 0, 0, 1080, 1920, "#FF0000" -> found_pos(想用坐标)
✅ If found_pos != "" Then → Click found_pos.x, found_pos.y
结果变量是 {x, y} 对象,不能直接当坐标用,需用 .x 和 .y 取值
⚠️ 避坑指南
搜索区域越大耗时越长。全屏搜索(1080×1920)可能需要 50-200ms,缩小搜索区域可显著提速。找到的是第一个匹配点,如果画面中有多个同色区域,不一定是你要的那个,建议缩小搜索区域精确定位。必须用 != "" 判断是否找到,不要用 == True。找不到时返回空字符串而非 false。
🖼️ 8. 图像识别
8.1 FindImage — 区域找图
FindImage "filename", x, y, width, height var
| 参数 | 类型 | 必填 | 说明 |
| filename | string | ✅ | 图片库中的文件名(需先在 A 端图片库上传) |
| x, y | number/var | ✅ | 搜索区域左上角 |
| width, height | number/var | ✅ | 搜索区域宽高 |
| sim | number | 否 | 相似度阈值 (0.0~1.0),默认 0.8 |
| retry | number | 否 | 未找到时重试次数,默认 0(不重试) |
| timeout | number | 否 | 超时时间(毫秒),0 表示不限 |
| var | 变量名 | ✅ | 找到的坐标,存储为 {x, y} 对象;未找到则为空字符串 |
✅ 正确示例
' 基本找图
FindImage "btn_login.png", 0, 0, 1080, 1920, 0.85 -> img_pos
If img_pos != "" Then
Click img_pos.x, img_pos.y
End If
' 带重试和超时
FindImage "btn_login.png", 0, 0, 1080, 1920, 0.8, retry=3, timeout=5000 -> img_pos
❌ 错误示例
❌ FindImage btn_login.png, 0, 0, 1080, 1920 -> pos
✅ FindImage "btn_login.png", 0, 0, 1080, 1920 -> pos
图片文件名必须加双引号,为字符串类型
⚠️ 避坑指南
图片需先在 A 端"图片库"面板上传,DSL 中通过文件名引用,下发任务时自动替换为 base64 数据。截图时务必在与运行环境相同的分辨率下截取,不同分辨率会导致找图失败。sim(相似度)建议 0.8-0.9:太低(0.6)容易误匹配,太高(0.99)因画面渲染差异导致找不到。如果找图不稳定,先用 retry=3, timeout=5000 自动重试。旧语法 FindImage x, y, w, h, sim -> var(无文件名)仍兼容但需通过步骤编辑器关联图片。
8.2 OCR — 区域文字识别 v214.2.90
OCR x1, y1, x2, y2 var
| 参数 | 类型 | 必填 | 说明 |
| x1 | number | ✅ | 识别区域左上角 X 坐标(仅纯数字) |
| y1 | number | ✅ | 识别区域左上角 Y 坐标(仅纯数字) |
| x2 | number | ✅ | 识别区域右下角 X 坐标(仅纯数字) |
| y2 | number | ✅ | 识别区域右下角 Y 坐标(仅纯数字) |
| var | 变量名 | ✅ | 识别出的文字内容存入该变量 |
✅ 正确示例
' 识别屏幕指定区域的文字(从(100,200)到(400,250))
OCR 100, 200, 400, 250 -> text_result
Log "识别结果: text_result"
' 判断文字内容后执行操作(从(540,800)到(940,840))
OCR 540, 800, 940, 840 -> btn_text
If btn_text contains "开始" Then
Click 540, 800
End If
❌ 错误示例
❌ OCR x_var, y_var, w, h -> text
✅ OCR 100, 200, 300, 400 -> text(从(100,200)到(300,400))
OCR 坐标参数只支持纯数字,不支持变量引用
⚠️ 避坑指南
OCR 使用 AI 视觉模型识别文字,坐标参数必须是纯数字(这是与其它指令的关键区别,不能传变量)。识别区域不宜过大(建议单行文字高度 30-50px),区域过大识别速度慢且准确率下降。OCR 结果可能包含空格和换行,判断时用 contains 而非 ==。如需读取区域内文字且支持变量坐标,改用 AIReadText。
8.3 OCRT — Tesseract 文字识别 v214.3.32
OCRT x1, y1, x2, y2[, x] var
| 参数 | 类型 | 必填 | 说明 |
| x1 | number | ✅ | 识别区域左上角 X 坐标(仅纯数字) |
| y1 | number | ✅ | 识别区域左上角 Y 坐标(仅纯数字) |
| x2 | number | ✅ | 识别区域右下角 X 坐标(仅纯数字) |
| y2 | number | ✅ | 识别区域右下角 Y 坐标(仅纯数字) |
| x | number | ❌ | 识别模式,默认 0。可选值:0=不限制 / 1=仅数字 / 2=数字+字母 |
| var | 变量名 | ✅ | 识别出的文字内容存入该变量 |
✅ 正确示例
' 使用 Tesseract 识别屏幕指定区域的文字(默认 mode=0 不限制)
OCRT 100, 200, 400, 250 -> text_result
Log "Tesseract识别结果: text_result"
' 仅识别数字(mode=1,适用于血量/分数等数字条)
OCRT 100, 200, 400, 250, 1 -> digits
' 识别数字+字母(mode=2)
OCRT 100, 200, 400, 250, 2 -> alnum
' 对比 OCR(ML Kit)与 OCRT(Tesseract)的识别效果
OCR 100, 200, 400, 250 -> mlkit_text
OCRT 100, 200, 400, 250 -> tess_text
Log "ML Kit: mlkit_text | Tesseract: tess_text"
❌ 错误示例
❌ OCRT x_var, y_var, w, h -> text
✅ OCRT 100, 200, 300, 400 -> text(从(100,200)到(300,400))
OCRT 坐标参数只支持纯数字,不支持变量引用
⚠️ 避坑指南
v214.3.32 改动:OCRT 基于 Tesseract OCR 引擎,与 OCR(ML Kit)并存。lang 固定为 eng(旧版 chi_sim+eng + 纯数字 whitelist 冲突会识别出汉字/字母/符号乱码,如 |" YHY 7 圃霄'),现在通过 x(mode)参数控制识别范围:0=不限制、1=仅数字、2=数字+字母。首次调用会从 assets 复制 traineddata 到内部存储(仅一次),后续调用直接使用。白名单调试:白名单账号会保存裁剪截图到本地调试目录(与 OCR 共享白名单机制),便于对比 OCR vs OCRT 的识别区域。语法与 OCR 完全一致(x1,y1,x2,y2 左上角+右下角),向后兼容旧 w/h 语义;旧 lang=xxx 命名参数仍可解析但已废弃(按 mode=0 处理)。
🤖 9. AI操作 v214.2.90
AI操作类指令使用 AI 视觉模型理解屏幕内容,支持自然语言描述定位元素、读取文字、判断状态等。所有 AI 指令均支持 -> var 箭头语法将结果存入变量。
AI指令区域参数格式
多个 AI 指令支持可选的 region 区域参数,格式如下:
| 格式 | 写法 | 说明 |
| 省略 | 不传 region 参数 | 全屏搜索 |
| 矩形区域 | x, y, w, h | 左上角坐标 + 宽高 |
| 圆形区域 | x, y, rN | 中心坐标 + 半径(r前缀) |
| 正方形区域 | x, y, zN | 中心坐标 + 半边长(z前缀) |
✅ 正确示例
' 全屏搜索
AIFindElement "登录按钮" -> pos
' 矩形区域搜索
AIFindElement "登录按钮", 100, 200, 300, 400 -> pos
' 圆形区域搜索(中心200,300 半径150)
AIFindElement "登录按钮", 200, 300, r150 -> pos
' 正方形区域搜索(中心200,300 半边长100)
AIFindElement "登录按钮", 200, 300, z100 -> pos
⚠️ 避坑指南
AI指令相比传统颜色/图像识别更智能但耗时更长(通常1-3秒),不适合高频调用。缩小搜索区域可显著提速。描述要具体明确("红色的关闭按钮"优于"按钮"),模糊描述会增加误识别率。
9.1 AIFindElement — AI找元素 v214.2.90
AIFindElement "描述" var
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 自然语言描述目标元素,如 "登录按钮"、"红色的关闭图标" |
| region | 区域参数 | 否 | 搜索区域,省略为全屏。支持 x,y,w,h / x,y,rN / x,y,zN |
| sim | number | 否 | 相似度阈值 (0.0~1.0),默认 0.7 |
| lang | string | 否 | 指定语言代码,如 "zh"、"en"、"ja"、"ko" |
| cross_lang | boolean | 否 | 启用跨语言识别,默认 false |
| var | 变量名 | 否 | 找到的坐标,存储为 {x, y} 对象;未找到则为空字符串 |
✅ 正确示例
' 基本用法:全屏搜索登录按钮
AIFindElement "登录按钮" -> pos
If pos != "" Then
Click pos.x, pos.y
End If
' 指定区域 + 相似度
AIFindElement "确认按钮", 0, 800, 1080, 400, sim=0.85 -> pos
' 跨语言识别
AIFindElement "Start Button", lang="en", cross_lang=true -> pos
❌ 错误示例
❌ AIFindElement 登录按钮 -> pos
✅ AIFindElement "登录按钮" -> pos
描述文本必须加双引号
⚠️ 避坑指南
sim 默认 0.7,对于颜色/形状差异大的元素建议提高到 0.85。描述越具体识别越准:"蓝色圆形确认按钮"优于"确认按钮"。同一画面有多个相似元素时,用 region 缩小搜索范围避免误识别。结果变量是 {x, y} 对象,判断是否找到用 != ""。
9.2 AIFindElementJ — AI找元素(日文) v214.2.90
AIFindElementJ "描述" var
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 日文描述目标元素,如 "ログインボタン" |
| var | 变量名 | 否 | 找到的坐标,存储为 {x, y} 对象;未找到则为空字符串 |
快捷方式:AIFindElementJ 等价于 AIFindElement "描述", lang="ja",专为日文游戏场景优化。
✅ 正确示例
AIFindElementJ "スタートボタン" -> pos
If pos != "" Then
Click pos.x, pos.y
End If
❌ 错误示例
❌ AIFindElementJ "スタートボタン", lang="ja" -> pos
✅ AIFindElementJ "スタートボタン" -> pos
AIFindElementJ 已内置 lang="ja",不需要再传 lang 参数
⚠️ 避坑指南
AIFindElementJ 是 AIFindElement 的日文快捷方式,不支持 region/sim 等额外参数。如需指定区域或相似度,请改用 AIFindElement "描述", lang="ja", sim=0.85。日文描述要准确,避免用中文描述日文界面元素。
9.3 AIFindElementK — AI找元素(韩文) v214.2.90
AIFindElementK "描述" var
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 韩文描述目标元素,如 "시작 버튼" |
| var | 变量名 | 否 | 找到的坐标,存储为 {x, y} 对象;未找到则为空字符串 |
快捷方式:AIFindElementK 等价于 AIFindElement "描述", lang="ko",专为韩文游戏场景优化。
✅ 正确示例
AIFindElementK "시작 버튼" -> pos
If pos != "" Then
Click pos.x, pos.y
End If
❌ 错误示例
❌ AIFindElementK 开始按钮 -> pos
✅ AIFindElementK "시작 버튼" -> pos
韩文快捷指令应使用韩文描述,且描述需加引号
⚠️ 避坑指南
与 AIFindElementJ 同理,AIFindElementK 不支持额外参数。韩文描述中"버튼"(按钮)、"시작"(开始)等常见词汇识别率较高。如遇识别不准,改用 AIFindElement 并调低 sim。
9.4 AIReadText — AI读文字 v214.2.90
支持三种调用形式:
| 形式 | 语法 | 说明 |
| 关键词搜索 | AIReadText "keyword" -> var | 全屏搜索包含关键词的文字区域 |
| 区域读取 | AIReadText region -> var | 读取指定区域内的所有文字 |
| 区域+关键词 | AIReadText "keyword", region -> var | 在指定区域内搜索包含关键词的文字 |
AIReadText var
| 参数 | 类型 | 必填 | 说明 |
| keyword | string | 否 | 关键词,用于在屏幕文字中定位目标 |
| region | 区域参数 | 否 | 搜索区域,省略为全屏。支持 x,y,w,h / x,y,rN / x,y,zN |
| var | 变量名 | 否 | 识别出的文字内容存入该变量 |
✅ 正确示例
' 形式1:全屏搜索关键词
AIReadText "金币" -> gold_text
Log "金币信息: gold_text"
' 形式2:读取指定区域文字
AIReadText 100, 50, 300, 30 -> area_text
Log "区域文字: area_text"
' 形式3:区域内搜索关键词
AIReadText "等级", 0, 0, 500, 100 -> level_text
Log "等级信息: level_text"
❌ 错误示例
❌ AIReadText 金币 -> text
✅ AIReadText "金币" -> text
关键词必须加引号,否则被当作变量引用
⚠️ 避坑指南
与 OCR 不同,AIReadText 的区域参数支持变量(OCR 只支持纯数字)。形式2(纯区域读取)和形式3(区域+关键词)的区别:形式2返回区域内所有文字,形式3只返回包含关键词的部分。读取数字时结果可能包含逗号/空格(如"1,234"),需自行处理。判断结果用 contains 而非 ==。
9.5 AICheck — AI判断 v214.2.90
AICheck "描述" var
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 自然语言描述判断条件,如 "弹窗是否出现"、"角色是否存活" |
| region | 区域参数 | 否 | 判断区域,省略为全屏。支持 x,y,w,h / x,y,rN / x,y,zN |
| sim | number | 否 | 相似度阈值 (0.0~1.0),默认 0.7 |
| timeout | number | 否 | 超时时间(毫秒),0 表示不等待,默认 0 |
| var | 变量名 | 否 | 判断结果 (true/false) 存入该变量 |
✅ 正确示例
' 判断弹窗是否出现
AICheck "确认弹窗是否出现" -> has_dialog
If has_dialog == True Then
AIFindElement "确认按钮" -> btn
Click btn.x, btn.y
End If
' 带超时等待:等待5秒内出现
AICheck "加载完成", timeout=5000 -> loaded
If loaded == True Then
Log "加载完成"
Else
Log "加载超时"
End If
❌ 错误示例
❌ AICheck "弹窗" -> has_dialog(描述太模糊)
✅ AICheck "确认弹窗是否出现" -> has_dialog
AICheck 是判断条件,描述应包含"是否"等判断语义,而非单纯描述元素
⚠️ 避坑指南
AICheck 返回 true/false(布尔值),判断时用 == True 或布尔简写 If has_dialog Then。不要用 != "" 判断(那是找元素/找图的判断方式)。timeout=0(默认)表示只检测一次立即返回;timeout>0 会轮询等待直到条件满足或超时。描述要用判断句式:"XX是否出现""XX是否完成"。
9.6 AISmartClick — AI智能点击 v214.2.90
AISmartClick "描述"
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 自然语言描述要点击的元素 |
| region | 区域参数 | 否 | 搜索区域,省略为全屏。支持 x,y,w,h / x,y,rN / x,y,zN |
| sim | number | 否 | 相似度阈值 (0.0~1.0),默认 0.9 |
便捷指令:AISmartClick 等价于先 AIFindElement 找到元素再 Click 点击,一步完成"找+点"操作。
✅ 正确示例
' 智能点击登录按钮
AISmartClick "登录按钮"
' 指定区域 + 高相似度
AISmartClick "确认按钮", 0, 800, 1080, 400, sim=0.9
❌ 错误示例
❌ AISmartClick "按钮" -> pos
✅ AISmartClick "按钮"(如需坐标请用 AIFindElement)
AISmartClick 不支持结果变量,它直接执行点击。如需获取坐标请改用 AIFindElement
⚠️ 避坑指南
AISmartClick 不支持 -> var 语法,它直接点击不返回坐标。如果想先判断元素是否存在再决定是否点击,应拆分为 AIFindElement + If + Click。AISmartClick 默认 sim=0.9(比 AIFindElement 的 0.7 更高),因为点击操作要求更高的准确性。点击失败不会报错,需自行判断是否成功。
9.7 AISmartWait — AI智能等待 v214.2.90
AISmartWait "描述" var
| 参数 | 类型 | 必填 | 说明 |
| 描述 | string | ✅ | 自然语言描述等待目标,如 "主界面加载完成" |
| region | 区域参数 | 否 | 等待区域,省略为全屏。支持 x,y,w,h / x,y,rN / x,y,zN |
| timeout | number | 否 | 超时时间(毫秒),默认 10000(10秒) |
| var | 变量名 | 否 | 等待结果 (true/false) 存入该变量 |
智能轮询:AISmartWait 会自动以间隔轮询方式检测目标是否出现,直到超时。比 Sleep + AICheck 循环更简洁。
✅ 正确示例
' 等待主界面加载完成(默认10秒超时)
AISmartWait "主界面加载完成" -> ready
If ready == True Then
Log "主界面已就绪"
Else
Log "等待超时"
End If
' 指定区域 + 30秒超时
AISmartWait "战斗结束", 0, 0, 1080, 1920, timeout=30000 -> done
❌ 错误示例
❌ AISmartWait "加载" -> ready(描述太模糊)
✅ AISmartWait "主界面加载完成" -> ready
等待描述应明确目标状态("加载完成""出现""结束"),模糊描述会导致误判
⚠️ 避坑指南
AISmartWait 返回 true/false,超时返回 false。替代了 Sleep + AICheck 循环的写法,更简洁高效。默认超时 10 秒,加载慢的场景需调大 timeout。轮询间隔由系统自动控制(约1-2秒),无需手动设置。与 AICheck 的区别:AICheck 的 timeout=0 默认只检测一次,AISmartWait 默认会轮询等待。
📱 10. 应用操作
10.1 LaunchApp — 启动应用
LaunchApp "包名"
| 参数 | 类型 | 必填 | 说明 |
| package | string | ✅ | Android 应用包名,如 "com.tencent.mm" |
✅ 正确示例
LaunchApp "com.tencent.mm" ' 启动微信
LaunchApp "com.example.game" ' 启动游戏
❌ 错误示例
❌ LaunchApp com.tencent.mm
✅ LaunchApp "com.tencent.mm"
包名必须加双引号,为字符串类型
⚠️ 避坑指南
包名必须完全准确,可在设备的"设置→应用"中查看。包名错误不会报错但应用不会启动。LaunchApp 后建议加 Sleep 等待应用启动完成(通常2-5秒),再执行后续操作。如果应用已在后台,LaunchApp 会将其切到前台而非冷启动。部分应用有启动闪屏页,需多等几秒。
10.2 CheckApp — 检查应用是否在前台
CheckApp "包名" var
| 参数 | 类型 | 必填 | 说明 |
| package | string | ✅ | Android 应用包名 |
| var | 变量名 | ✅ | 结果 (true/false) 存入该变量 |
✅ 正确示例
LaunchApp "com.tencent.mm"
Sleep 2000
CheckApp "com.tencent.mm" -> is_running
If is_running == True Then
Log "微信已启动"
Else
Log "微信启动失败"
End If
❌ 错误示例
❌ CheckApp "com.tencent.mm"
✅ CheckApp "com.tencent.mm" -> is_running
CheckApp 必须用 -> 指定结果变量,否则判断结果无处存储
⚠️ 避坑指南
CheckApp 检查的是"应用是否在前台"而非"应用是否在运行"。应用在后台时返回 false。返回值是 true/false(布尔值),判断时用 == True 或布尔简写。部分定制 ROM 的多窗口模式可能影响检测结果。
🕐 11. 系统操作 v214.2.90
11.1 WaitUntil — 等待到指定时间 v214.2.90
WaitUntil "HH:mm"
| 参数 | 类型 | 必填 | 说明 |
| HH:mm | string | ✅ | 目标时间,24小时制格式,如 "08:00"、"23:30" |
说明:脚本执行到 WaitUntil 时会暂停,直到系统时间到达指定时间后继续执行。适用于定时任务场景,如每天固定时间签到。
✅ 正确示例
' 等待到早上8点再执行
Log "等待到08:00..."
WaitUntil "08:00"
Log "时间到,开始执行"
LaunchApp "com.example.game"
❌ 错误示例
❌ WaitUntil 08:00
✅ WaitUntil "08:00"
时间参数必须加引号,为字符串类型
❌ 错误示例
❌ WaitUntil "8:00"
✅ WaitUntil "08:00"
小时必须是两位数(24小时制),8点应写为08
⚠️ 避坑指南
WaitUntil 是阻塞式等待,脚本会完全暂停直到指定时间。如果当前时间已超过目标时间(如当前14:00,WaitUntil "08:00"),会立即通过(不等到第二天8点)。格式必须是 HH:mm 两位小时+两位分钟。不要用 WaitUntil 做短时间等待(如 WaitUntil "08:01"),短等待用 Sleep。定时签到场景建议配合 GetTime 记录日志。
11.2 GetTime — 获取当前时间 v214.2.90
GetTime var
| 参数 | 类型 | 必填 | 说明 |
| var | 变量名 | ✅ | 当前时间字符串存入该变量,格式为 yyMMddHHmmss(如 260623143052) |
✅ 正确示例
GetTime -> current_time
Log "当前时间: current_time"
' 根据时间判断是否执行
GetTime -> now
If now >= "260623080000" Then
Log "已到指定时间"
End If
❌ 错误示例
❌ GetTime 返回 HH:mm:ss
✅ GetTime 返回 yyMMddHHmmss(如 260623143052)
GetTime 返回14位时间戳格式(年月日时分秒各两位),非 HH:mm:ss
❌ 错误示例
❌ GetTime(不写结果变量)
✅ GetTime -> now
GetTime 必须用 -> 指定结果变量
⚠️ 避坑指南
返回格式是 yyMMddHHmmss(14位),如 260623143052 表示2026年6月23日14:30:52。年份是两位(26=2026),不是四位。时间比较时按字符串字典序比较(因为是定长数字字符串,字典序等价于数值序)。提取小时可用字符串截取:Set hour = current_time 然后取第9-10位。注意时区为设备本地时区。
🔤 12. 变量与表达式
12.1 注释
支持两种注释符号,行首注释和行尾注释均可:
| 符号 | 用法 | 示例 |
' 单引号 | 行首或行尾注释 | ' 这是注释 或 Click 100, 200 ' 行尾注释 |
# 井号 | 行首或行尾注释 | # 这也是注释 或 Sleep 1000 # 等待1秒 |
✅ 正确示例
' 整行注释:说明脚本用途
# 也可以用井号注释
Set count = 0 ' 行尾注释:初始化计数器
Click 100, 200 # 点击按钮
❌ 错误示例
❌ // 这是注释
✅ ' 这是注释 或 # 这是注释
不支持 C 风格的 // 或 /* */ 注释
⚠️ 避坑指南
单引号 ' 同时也是字符串包裹符。当单引号出现在行首或逗号后,解析为注释;出现在参数位置则解析为字符串。建议字符串统一用双引号,注释用单引号或井号,避免歧义。行尾注释的 # 与参数之间需有空格,否则可能被当作参数的一部分。
12.2 Set — 设置变量(赋值即声明)
Set var = value
DSL 没有专门的变量声明语句(无 Dim/Var 等),变量通过 Set 赋值时自动创建。Set 关键字不可省略。
| 参数 | 类型 | 必填 | 说明 |
| var | 变量名 | ✅ | 等号左边的变量名不加 $ 前缀 |
| value | any | ✅ | 值:数字直接写、字符串需加引号、支持表达式;直接使用变量名引用变量值 |
✅ 正确示例
Set count = 0 ' 创建数值变量
Set name = "hello" ' 创建字符串变量
Set threshold = 10 ' 数值直接写
Set sum = a + b ' 算术表达式
Set result = color ' 把变量color的值赋给result
Set $count = 5 ' $前缀可选,与 Set count = 5 等效
❌ 错误示例
❌ count = 0(缺少 Set 关键字)
✅ Set count = 0
Set 关键字不可省略,缺少 Set 解析器无法识别赋值语句
❌ 错误示例
❌ Set 变量名 = 10
✅ Set var_name = 10
变量名只支持ASCII字符(字母/数字/下划线),不支持中文
⚠️ 避坑指南
等号左边是赋值目标,不加 $;等号右边直接使用变量名引用变量值。变量名只支持 ASCII 字符(字母/数字/下划线),不支持中文变量名。数字直接写(Set n = 10),字符串必须加引号(Set s = "abc")。v214.2.63 起禁止 Set 和 SetGlobal 同名变量混用,会触发解析错误。
12.3 变量自增/自减
变量名直接使用即可引用变量值,无需加 $ 前缀。
| 写法 | 是否正确 | 说明 |
Set a = a + 1 | ✅ 正确 | 直接使用变量名引用变量值 |
Set a = $a + 1 | ✅ 正确 | $ 前缀显式标识变量,效果相同 |
a = a + 1 | ❌ 错误 | 缺少 Set 关键字,解析器不识别 |
✅ 正确示例
Set count = 0
' 自增1
Set count = count + 1
' 自增5
Set count = count + 5
' 自减1(注意:减号两侧不加空格!)
Set count = count-1
' 乘2
Set count = count * 2
' 除3
Set avg = total / 3
⚠️ 避坑指南(减法运算陷阱)
变量名与减号之间不要加空格,否则表达式中的空格会导致算术解析失败,变量值被当作字符串拼接!
| 写法 | 结果 | 说明 |
Set lou = $lou-1 | ✅ 正确:lou减1 | $前缀明确变量边界,无空格,算术解析正确 |
Set lou = lou-1 | ✅ 正确:lou减1 | 裸变量名无空格,同样正确 |
Set lou = lou - 1 | ❌ 错误:变成字符串拼接 | 空格导致算术解析器中断,结果变为 "3-1" 而非 2 |
推荐写法:减法运算符两侧不加空格,如
Set lou = $lou-1。加法和乘除法无此问题。
12.4 变量引用
在任意数值/字符串位置均可直接使用变量名引用变量值,解析时自动替换为当前值。
未定义的变量返回空字符串 ""。
✅ 正确示例
Set base_x = 100
Click base_x, 200 ' 等价于 Click 100, 200
InputText username
Sleep delay_ms
Set next_x = base_x + 50 ' 表达式中引用变量
⚠️ 避坑指南
未定义的变量返回空字符串 "",不会报错。这可能导致隐蔽的 bug:如 Click undefined_var, 200 不会报错但点击无效。建议在使用变量前先用 Set 初始化。对象类型变量(FindColor/FindImage 的结果)用 .x 和 .y 取值,直接引用对象本身会得到 [object] 字符串。
12.5 算术表达式 v157
支持加减乘除四则运算和括号嵌套,可混合变量引用。字符串支持 + 拼接。
| 运算符 | 说明 | 示例 |
+ | 加 / 字符串拼接 | a + b、"hello " + name |
- | 减(注意空格陷阱) | count-1(不加空格) |
* | 乘 | width * 2 |
/ | 除 | total / 3 |
() | 括号 | (a + b) * c |
✅ 正确示例
Set pos_x = base + 50
Set half_screen = 1080 / 2
Set total = (x + y) * scale
Set msg = "坐标: (" + x + ", " + y + ")"
Log msg
❌ 错误示例
❌ Set val = a - b(减法有空格)
✅ Set val = a-b
减法运算符两侧有空格会导致字符串拼接而非算术运算
⚠️ 避坑指南
+ 运算符既是加法也是字符串拼接:当两个操作数都是数字时做加法,任一为字符串则做拼接。如 "3" + 5 结果是 "35" 而非 8。减法运算符两侧绝对不能加空格(见12.3避坑指南),这是最常见的算术表达式 bug。除法是整数除法还是浮点除法取决于操作数类型。
12.6 条件表达式
用于 If 和 While 语句中,格式为:左值 操作符 右值
| 操作符 | 说明 | 示例 |
== | 等于 | color == "#FFFFFF" |
!= | 不等于 | count != 0 |
> | 大于 | count > 5 |
< | 小于 | count < 10 |
>= | 大于等于 | score >= 60 |
<= | 小于等于 | score <= 100 |
contains | 字符串包含 | name contains "admin" |
notContains | 字符串不包含 | name notContains "test" |
~= | 颜色模糊匹配(D44) v214.2.10 | color_value ~= "#346BB8"(默认容差0.85) |
~= "#RRGGBB" N | 自定义容差 v214.2.10 | color_value ~= "#346BB8" 0.9(容差0~1,值越大越精确) |
布尔简写
只有变量名时,自动视为 var == True:
✅ 正确示例
If running Then ' 等价于 If running == True Then
Click 100, 200
End If
❌ 错误示例
❌ If x > 1 And y > 2 Then
✅ 嵌套If:If x > 1 Then → If y > 2 Then
不支持 And/Or/Not 逻辑运算符,需用嵌套 If 实现
❌ 错误示例
❌ If x = 1 Then(单个等号)
✅ If x == 1 Then(双等号)
条件判断用双等号 ==,单个 = 是赋值符号
字符串包含判断示例
✅ 正确示例
' 判断字符串是否包含子串
If name contains "admin" Then
Log "管理员账号"
End If
If name notContains "test" Then
Log "非测试账号"
End If
颜色模糊匹配示例 v214.2.10
✅ 正确示例
' 默认容差0.85,适合大多数场景
GetColor 540, 960 -> color_value
If color_value ~= "#346BB8" Then
Click 540, 960
Log "颜色近似匹配"
End If
' 自定义容差0.9,更精确
If color_value ~= "#346BB8" 0.9 Then
Log "高精度颜色匹配"
End If
~= 算法说明:分别计算 R/G/B 三个通道的差值比 (255 - |差值|) / 255,三个比值相乘得到最终相似度(取2位小数截断)。容差范围 0~1,默认 0.85。值越大要求越精确:0.7=宽松、0.85=默认、0.95=高精度。非颜色值(非 #RRGGBB 格式)退化为精确字符串比较。
⚠️ 避坑指南
条件表达式不支持 And/Or/Not 逻辑运算符,这是最常见的新手错误。需要"且"逻辑用嵌套 If,需要"或"逻辑用多个 If + Goto 或 Label。== 是比较运算符,= 是赋值运算符,两者不能混用。布尔简写只适用于变量(If running Then),不适用于表达式。
12.7 SetGlobal — 设置全局持久化变量 v214.2.90
SetGlobal var = value
| 参数 | 类型 | 必填 | 说明 |
| var | 变量名 | ✅ | 全局变量名,跨任务共享 |
| value | any | ✅ | 变量值,与 Set 语法一致 |
说明:SetGlobal 设置的变量存储在全局持久化层,跨任务共享且设备重启后仍然保留。适用于需要在不同脚本间传递状态或持久化配置的场景。
✅ 正确示例
' 设置全局计数器(跨任务共享)
SetGlobal total_runs = 0
SetGlobal total_runs = total_runs + 1
Log "总运行次数: total_runs"
❌ 错误示例
❌ SetGlobal count = 0(普通计数器)
✅ Set count = 0(只有跨任务才用 SetGlobal)
SetGlobal 用于跨任务持久化,普通变量用 Set 即可
⚠️ 避坑指南
变量名冲突检测:同一个变量名不能同时被 Set(局部)和 SetGlobal(全局)使用,解析器会报错"变量名冲突"。全局变量不会随任务结束而清除,如果需要在任务结束后清理,需手动 SetGlobal var = ""。全局变量名建议加 g_ 前缀以便区分,如 SetGlobal g_total_runs = 0。
12.8 InitGlobal — 条件初始化全局变量 v214.2.90
InitGlobal var = value
| 参数 | 类型 | 必填 | 说明 |
| var | 变量名 | ✅ | 全局变量名 |
| value | any | ✅ | 初始值(仅在变量不存在时赋值) |
与 SetGlobal 的区别:SetGlobal 是强制赋值(每次执行都覆盖),InitGlobal 是条件赋值(变量已存在则跳过)。适用于"首次运行初始化、后续运行保留"的场景。
✅ 正确示例
' 首次运行初始化计数器,后续运行保留累计值
InitGlobal g_run_count = 0
SetGlobal g_run_count = g_run_count + 1
Log "第 g_run_count 次运行"
❌ 错误示例
❌ InitGlobal g_count = g_count + 1(用 InitGlobal 做累加)
✅ SetGlobal g_count = g_count + 1(累加用 SetGlobal)
InitGlobal 只在变量不存在时赋值,已存在则跳过,不能用于累加
⚠️ 避坑指南
InitGlobal 与 SetGlobal 混淆是最常见的全局变量 bug。InitGlobal = "如果不存在则创建"(初始化),SetGlobal = "强制覆盖"(更新)。典型模式:InitGlobal 初始化 → SetGlobal 更新。如果发现全局变量值不更新,检查是否误用了 InitGlobal 做赋值。
12.9 Pause — 脚本自暂停 v214.2.90
Pause
暂停当前脚本的执行,需要通过 Resume 或 B端手动恢复。无参数。
✅ 正确示例
' 执行到某步后暂停,等待人工确认
Click 540, 1200
Log "已点击,暂停等待确认"
Pause
Log "已恢复,继续执行"
❌ 错误示例
❌ Pause 5000(带参数等待)
✅ Sleep 5000(等待用 Sleep)
Pause 无参数,是暂停而非延时等待;延时用 Sleep
⚠️ 避坑指南
Pause 是无限期暂停,脚本会停在 Pause 行等待恢复,不会自动继续。必须通过 Resume 命令或 B端操作恢复。如果脚本暂停后无人恢复,设备会一直处于"暂停"状态。不要用 Pause 替代 Sleep 做延时。
12.10 Resume — 脚本自恢复 v214.2.90
Resume
恢复当前脚本的执行(取消 Pause 暂停状态)。无参数。
✅ 正确示例
' 通常在子程序或条件分支中恢复
If should_continue == True Then
Resume
End If
⚠️ 避坑指南
Resume 只对当前脚本自身的 Pause 有效,不能恢复其他脚本的暂停。如果脚本未处于暂停状态,Resume 无效果但也不会报错。B端也可手动恢复暂停的脚本。
12.11 Start — 启动副任务 v214.2.90
Start "scriptID"
| 参数 | 类型 | 必填 | 说明 |
| scriptID | string | ✅ | 目标脚本ID,必须加双引号 |
主任务通过 Start 启动另一个脚本(副任务),实现多脚本协同。单向控制:主任务控制副任务,不可反向。
✅ 正确示例
' 启动副任务
Start "abc123"
Log "副任务已启动"
❌ 错误示例
❌ Start abc123(不加引号)
✅ Start "abc123"
脚本ID是字符串类型,必须加双引号
⚠️ 避坑指南
Start 是异步的,启动副任务后主任务不会等待副任务完成,而是立即继续执行下一行。如果需要等待副任务完成,需要用 Sleep 或轮询 CheckApp 等方式自行实现。重复 Start 同一脚本会触发幂等保护,不会重复启动。
12.12 Stop — 停止副任务 v214.2.90
Stop "scriptID"
| 参数 | 类型 | 必填 | 说明 |
| scriptID | string | ✅ | 目标脚本ID,必须加双引号 |
✅ 正确示例
' 停止副任务
Stop "abc123"
Log "副任务已停止"
⚠️ 避坑指南
Stop 只能停止由当前主任务 Start 启动的副任务。如果目标脚本未在运行,Stop 不会报错但也不产生效果。停止副任务是立即生效的,副任务不会执行完当前行。
12.13 PauseScript — 暂停副任务 v214.2.90
PauseScript "scriptID"
| 参数 | 类型 | 必填 | 说明 |
| scriptID | string | ✅ | 目标脚本ID,必须加双引号 |
✅ 正确示例
' 暂停副任务(区别于 Pause 自暂停)
PauseScript "abc123"
Log "副任务已暂停"
❌ 错误示例
❌ PauseScript abc123(不加引号)
✅ PauseScript "abc123"
脚本ID是字符串类型,必须加双引号
⚠️ 避坑指南
PauseScript vs Pause 的区别:Pause 暂停当前脚本自身(无参数),PauseScript "id" 暂停指定的副任务(需参数)。两者容易混淆。暂停的副任务可用 ResumeScript 恢复。
12.14 ResumeScript — 恢复副任务 v214.2.90
ResumeScript "scriptID"
| 参数 | 类型 | 必填 | 说明 |
| scriptID | string | ✅ | 目标脚本ID,必须加双引号 |
✅ 正确示例
' 恢复已暂停的副任务
ResumeScript "abc123"
Log "副任务已恢复"
⚠️ 避坑指南
ResumeScript 只能恢复被 PauseScript 暂停的副任务。如果目标脚本未暂停,调用无效果。与 Resume(恢复自身)区分:Resume 无参数恢复当前脚本,ResumeScript "id" 带参数恢复指定副任务。
🔀 13. 控制流
13.1 If / Then / Else / End If — 条件分支
If 条件表达式 Then
语句块
Else
语句块
End If
| 部分 | 说明 |
| 条件表达式 | 见 12.6 条件表达式(支持 ==, !=, >, <, contains, notContains, ~=) |
| Then 块 | 条件为真时执行 |
| Else 块 | 可选,条件为假时执行 |
| End If | 结束标记(也可用 EndIf 或 End,推荐 End If) |
✅ 正确示例
If color_match == True Then
Click 100, 200
Log "点击成功"
Else
Log "颜色不匹配,跳过"
End If
❌ 错误示例
❌ If x > 1 And y > 2 Then(使用 And 逻辑运算符)
✅ 嵌套 If:If x > 1 Then → If y > 2 Then
条件表达式不支持 And/Or/Not 逻辑运算符,需用嵌套 If 实现
❌ 错误示例
❌ If x = 1 Then(单个等号)
✅ If x == 1 Then(双等号)
条件判断用双等号 ==,单个 = 是赋值符号
⚠️ 避坑指南
最常见的三个 If 错误:1) 使用 And/Or/Not(不支持,用嵌套 If);2) 使用单个 = 比较(应用 ==);3) 忘记写 Then 关键字。End If 也可写成 EndIf 或裸 End,但推荐完整写法以避免歧义。Else 块是可选的。
13.2 While / End While — 条件循环
While 条件表达式
语句块
End While
| 参数 | 说明 |
| 条件表达式 | 条件为真时持续执行循环体 |
| max_iterations | 默认 1000 次上限,防止无限循环 |
| End While | 结束标记(也可用 EndWhile 或 End) |
✅ 正确示例
Set count = 0
While count < 5
Click 100, 200
Sleep 1000
Set count = count + 1
End While
❌ 错误示例
❌ While True(无限循环)
✅ While count < 1000(有界条件)
While True 永远为真,1000次后强制退出;应使用有界条件
⚠️ 避坑指南
While 循环有 1000 次硬上限,超过后强制退出并记录警告。如果需要超过 1000 次循环,需在循环体内用 Goto 跳转实现外部循环。循环体内务必修改条件变量(如 Set count = count + 1),否则会触发 1000 次上限。While True 虽然能写但会被 1000 次限制截断,不推荐。
13.3 Repeat / End Repeat — 固定次数循环
Repeat times
语句块
End Repeat
| 参数 | 类型 | 说明 |
| times | number/var | 重复次数,支持表达式和变量 |
| End Repeat | keyword | 结束标记(也可用 EndRepeat 或 End) |
✅ 正确示例
' 固定次数
Repeat 5
Click 100, 200
Sleep 500
End Repeat
' 使用变量
Set n = 3
Repeat n
Log "循环中"
End Repeat
❌ 错误示例
❌ End(裸结束标记)
✅ End Repeat(完整结束标记)
避免歧义,应使用完整的结束标记 End Repeat
⚠️ 避坑指南
Repeat 的次数在进入循环时确定,循环体内修改次数变量不会影响已开始的循环次数。如果 times 为 0 或负数,循环体不执行。Repeat 同样受 1000 次上限保护,设置超过 1000 会被截断。
13.4 嵌套控制流
If / While / Repeat 支持任意深度嵌套,注意结束标记要一一对应。
✅ 正确示例
Repeat 3
If running == True Then
While count < 10
Click 100, 200
Sleep 1000
Set count = count + 1
End While
Else
Log "已停止"
End If
End Repeat
⚠️ 避坑指南
嵌套时结束标记必须严格匹配:每个 If 对应一个 End If,每个 While 对应一个 End While,每个 Repeat 对应一个 End Repeat。嵌套过深时推荐用缩进提高可读性。虽然裸 End 可以作为通用结束标记,但在嵌套场景下极易导致匹配错误,强烈推荐使用完整的结束标记。
🏷️ 14. 跳转
14.1 Label — 定义标签
Label label_name
| 参数 | 类型 | 必填 | 说明 |
| label_name | 标识符 | ✅ | 标签名(字母/数字/下划线),全局唯一 |
✅ 正确示例
' 定义标签
Label start_here
Label loop_top
❌ 错误示例
❌ Label "start"(加引号)
✅ Label start(不加引号)
标签名是标识符不是字符串,不需要加引号
⚠️ 避坑指南
标签名必须全局唯一,重复定义同名标签会导致 Goto 跳转到第一个匹配的标签。标签名只能使用 ASCII 字母、数字和下划线,不支持中文。标签本身不执行任何操作,只是 Goto 的跳转目标。
14.2 Goto — 跳转到标签
Goto label_name
跳转到指定标签位置继续执行。如果目标标签不存在,Goto 被忽略(不报错)。
✅ 正确示例
Goto skip
Click 100, 200 ' 被跳过
Label skip
Click 300, 400 ' 从这里继续执行
❌ 错误示例
❌ Goto "skip"(加引号)
✅ Goto skip(不加引号)
Goto 的参数是标签名(标识符),不是字符串
⚠️ 避坑指南
跳转到不存在的标签会被静默忽略,不会报错但脚本行为可能不符合预期。建议优先使用控制流语句(If/While/Repeat)替代 Goto,代码可读性更好。Goto 可用于跳出 While 循环(类似 break),也可用于实现超过 1000 次限制的外部循环(Goto 回循环开头)。避免向后跳转造成死循环。
14.3 GotoLine — 跳转到源码行号 v214.2.90
GotoLine N
| 参数 | 类型 | 必填 | 说明 |
| N | number | ✅ | 源码行号(从1开始),跳转到该行继续执行 |
✅ 正确示例
' 跳转到第20行继续执行
GotoLine 20
' 调试:跳过某段代码
GotoLine 50 ' 跳过中间的调试代码
❌ 错误示例
❌ GotoLine "20"(加引号)
✅ GotoLine 20(纯数字)
行号是纯数字,不支持字符串或变量
⚠️ 避坑指南
GotoLine 是调试专用命令,行号对应 DSL 源码的物理行号(从1开始,含空行和注释行)。如果插入或删除行,原行号会偏移导致跳转位置错误。生产环境强烈推荐用 Label/Goto 替代,因为标签名不会因行号变化而失效。GotoLine 的参数只能是纯数字常量,不支持变量。
📦 15. 子程序
子程序是可复用的步骤集合,支持参数化、返回值、嵌套调用。采用 Sub/EndSub 语法在 DSL 编辑器中直接定义。
15.1 Sub / EndSub — 定义子程序 v158
Sub Name(param1, param2, ...)
语句块
EndSub
| 部分 | 类型 | 必填 | 说明 |
| Name | 标识符 | ✅ | 子程序名称,Call 时按名称匹配 |
| param1, param2... | 参数名列表 | 否 | 逗号分隔的参数名,自动识别为 string 类型 |
| return_var | 变量名 | 否 | 箭头 -> 后指定返回值变量名 |
| 语句块 | DSL 语句 | ✅ | 子程序内部执行的步骤,与主脚本语法完全一致 |
| EndSub | keyword | ✅ | 子程序结束标记 |
✅ 正确示例
' 基本子程序:无参数无返回值
Sub Greet()
Log "hello"
EndSub
' 带参数的子程序
Sub Login(user, password)
Click 300, 400
InputText user
Click 300, 500
InputText password
Click 300, 600
EndSub
' 带返回值的子程序
Sub CheckColor(x, y, target) -> match
IsColor x, y, target -> match
EndSub
❌ 错误示例
❌ Sub name(x=10)(默认参数值)
✅ Sub name(x)(只写参数名)
不支持默认参数值,参数列表只写参数名
⚠️ 避坑指南
子程序定义不会被执行,只有在被 Call 调用时才执行。EndSub 是必须的结束标记,不能省略。参数自动识别为 string 类型,如需数字运算在子程序内部用 Set 转换。子程序内可以定义局部变量,不会影响主脚本的同名变量。不支持默认参数值和可选参数。
15.2 Call — 调用子程序
支持三种参数传递方式:括号语法(推荐)、位置参数和 命名参数。
方式一:括号语法(推荐)v173
Call Name
方式二:位置参数
Call "子程序名"
方式三:命名参数
Call "子程序名"
✅ 正确示例
' 括号语法(推荐,简洁直观)
Call Login("admin", "123456") -> login_ok
Call pd(1220, 43, "#D1C1A8")
' 位置参数(按定义顺序传值)
Call "Login", "admin", "123456" -> login_ok
' 命名参数(明确指定参数名)
Call "Login", user="admin", password="123456" -> login_ok
' 无参数调用
Call "Greet"
❌ 错误示例
❌ Call sub(1, 2, key=3)(混合参数)
✅ 纯位置 Call sub(1, 2) 或纯命名 Call sub(key1=1, key2=2)
不支持混合参数,位置参数和命名参数不可混用
❌ 错误示例
❌ Return(使用 Return 返回)
✅ 用 Goto 跳到 EndSub 前(或直接让 Sub 执行到 EndSub)
不存在 Return 命令,子程序执行到 EndSub 自动返回
⚠️ 避坑指南
三种调用方式不可混用:括号语法、位置参数、命名参数三选一,不能在同一 Call 中混用位置和命名参数。子程序嵌套调用最大深度 10 层,自动检测循环引用(A→B→A 会跳过)。不存在 Return 命令,子程序执行到 EndSub 自动返回;如需提前返回,用 Goto 跳到 EndSub 前的 Label。括号语法是 v173 新增的推荐写法。
15.3 主脚本 + 子程序混合
主脚本中的 Sub/EndSub 块会被自动识别为子程序定义,不干扰主流程执行。主脚本中可直接 Call 调用来复用已定义的子程序。
✅ 正确示例
' ===== 子程序定义 =====
Sub Login(user, password)
LaunchApp "com.tencent.mm"
Sleep 2000
Click 300, 400
InputText user
Click 300, 500
InputText password
Click 300, 600
EndSub
' ===== 主脚本 =====
Set username = "admin"
Set password = "123456"
Call Login(username, password) -> login_ok
If login_ok == True Then
Log "登录成功,开始主流程"
Repeat 3
Click 540, 800
Sleep 500
End Repeat
Else
Log "登录失败,退出"
PressBack
End If
⚠️ 避坑指南
Sub/EndSub 块在主脚本中的位置不影响执行:可以放在主脚本前、后或中间,解析器会自动提取所有 Sub 定义,主脚本从第一个非 Sub 语句开始执行。但为了可读性,推荐将所有 Sub 定义放在主脚本之前或之后。子程序定义不会在主流程中执行,只有 Call 才会触发执行。
15.4 子程序 REST API(兼容方式)
除了在 Web 界面用 DSL 创建外,也可通过 REST API 程序化创建子程序:
| 方法 | 端点 | 说明 |
GET | /api/action-groups | 获取所有子程序列表(含 dsl_code) |
POST | /api/action-groups | 创建子程序(body 含 dsl_code 字段) |
PUT | /api/action-groups/<id> | 更新子程序 |
DELETE | /api/action-groups/<id> | 删除子程序 |
说明:REST API 方式创建的子程序与 DSL 编辑器中定义的 Sub/EndSub 效果一致,都可通过 Call 调用。
📖 16. 完整示例
示例 1:简单点击脚本
✅ 启动微信 → 等待 → 点击 → 输入
' 启动微信,点击登录
LaunchApp "com.tencent.mm"
Sleep 2000
Click 540, 1200
Sleep 1000
Click 540, 800
InputText "hello"
Log "任务完成"
要点:每次操作后加 Sleep 等待 UI 响应,避免点击落空。
示例 2:颜色检测 + 条件分支
✅ 检测颜色决定下一步操作
' 检测某个位置的颜色,决定下一步操作
GetColor 100, 200 -> bg_color
Log "背景颜色: bg_color"
IsColor 540, 960, "#FF0000", 15 -> is_red
If is_red == True Then
Click 540, 960
Log "点击红色区域"
Else
Swipe 540, 1500, 540, 500, 300
Log "向上滑动"
End If
要点:IsColor 的容差参数 15 表示 RGB 三通道各允许 15 的偏差。
示例 3:循环找图
✅ 10次尝试找图,找到后点击
Set found = False
Set attempts = 0
While attempts < 10
FindImage "target.png", 0, 0, 1080, 1920, 0.8, retry=3, timeout=5000 -> pos
If pos != "" Then
Click pos.x, pos.y
Log "找到目标 (pos.x, pos.y)"
Set found = True
Goto done
End If
Sleep 1000
Set attempts = attempts + 1
End While
Label done
If found == True Then
Log "查找成功"
Else
Log "查找失败,10次尝试未找到"
End If
要点:Goto done 用于跳出 While 循环(类似 break)。pos != "" 判断找图是否成功。
示例 4:综合实战(游戏自动签到)
✅ 完整的游戏签到流程
' ===== 游戏签到脚本 =====
Log "===== 开始签到 ====="
' 1. 启动游戏
LaunchApp "com.example.game"
Sleep 3000
' 2. 等待主界面加载(检测特征颜色)
Set loaded = False
Set retry = 0
While retry < 20
IsColor 540, 1800, "#FFD700", 10 -> loaded
If loaded == True Then
Goto main_ready
End If
Sleep 1000
Set retry = retry + 1
End While
Log "主界面加载超时"
PressBack
Goto exit
' 3. 点击签到入口
Label main_ready
Log "主界面已加载"
Click 900, 200
Sleep 1500
' 4. 点击签到按钮
IsColor 540, 1200, "#00FF00", 15 -> btn_ready
If btn_ready == True Then
Click 540, 1200
Sleep 1000
Log "签到成功"
Else
Log "签到按钮未找到"
End If
' 5. 返回桌面
Label exit
PressHome
Log "===== 签到结束 ====="
要点:综合运用了 LaunchApp、IsColor 轮询、Goto 跳转、Label 标记、条件分支等。Goto exit 实现超时退出路径。
📐 17. 参数区 (v213)
用 '########参数区 标记将变量暴露到 B端,支持类型定义,让 B端用户在运行脚本前填写参数。
17.1 基本语法
Set 变量名 = 默认值
参数区位于 '########参数区 和下一个 '######## 标记之间。
17.2 类型定义
在注释行使用 [类型, 属性...] 语法定义 B端的 UI 控件:
| 类型 | 写法 | 可选属性 | B端控件 |
| 文本 | '角色名 [文本, placeholder="请输入"] | placeholder | 文本输入框 |
| 数字 | '数量 [数字, min=1, max=10, step=1] | min, max, step | 数字输入框 |
| 下拉 | '目标模式 [下拉, 模式A, 模式B, 模式C] | 选项列表(逗号分隔) | 下拉选择框 |
| 复选框 | '启用 [复选框] | 无 | 复选框 |
不标注类型的参数默认为文本输入。
17.3 完整示例
✅ 参数区完整示例
'########参数区
'执行次数 [数字, min=1, max=10, placeholder="请输入1-10的执行次数"]
Set jiaose = 3
'目标模式 [下拉, 模式A, 模式B, 模式C, 模式D]
Set fuben_type = 模式A
'自动返回 [复选框]
Set auto_return = 1
'角色名 [文本, placeholder="请输入角色名"]
Set role_name = "默认角色"
'攻速间隔(ms) [数字, min=50, max=5000, step=50]
Set gs = 100
'########脚本区
Click 100, 200
If gs > 200 Then
Log "快速模式"
End If
⚠️ 避坑指南
参数区外的 Set 语句不会被提取到 B端。Sub 内部或脚本区的变量不在参数面板中显示。参数区的 Set 语句既设置默认值又声明参数,B端用户填写的值会覆盖默认值。类型定义必须写在注释行中(以 ' 开头),紧跟在对应 Set 语句的上一行。
⚡ 18. 快速语法速查表
点击Click x, y
长按LongClick x, y[, dur]
滑动Swipe x1, y1, x2, y2[, dur]
输入InputText "text"
等待Sleep ms
返回PressBack
HomePressHome
日志Log "msg"
取色GetColor x, y -> var
判色IsColor x, y, "c"[, t] -> var
找色FindColor x, y, w, h, "c"[, t] -> var
找图FindImage "fn", x, y, w, h[, sim][, retry=N][, timeout=M] -> var
OCROCR x1, y1, x2, y2 -> var v214.2.90
OCRTOCRT x1, y1, x2, y2[, x] -> var v214.3.32
AI找AIFindElement "desc"[, region][, sim=N] -> var v214.2.90
AI找日AIFindElementJ "desc" -> var v214.2.90
AI找韩AIFindElementK "desc" -> var v214.2.90
AI读AIReadText ["kw"][, region] -> var v214.2.90
AI判AICheck "desc"[, region][, sim=N][, timeout=N] -> var v214.2.90
AI点AISmartClick "desc"[, region][, sim=N] v214.2.90
AI等AISmartWait "desc"[, region][, timeout=N] -> var v214.2.90
启动LaunchApp "pkg"
检查CheckApp "pkg" -> var
等时WaitUntil "HH:mm" v214.2.90
取时GetTime -> var v214.2.90
赋值Set var = value
全局赋SetGlobal var = value v214.2.90
全局初InitGlobal var = value v214.2.90
暂停Pause v214.2.90
恢复Resume v214.2.90
启任务Start "scriptID" v214.2.90
停任务Stop "scriptID" v214.2.90
暂停任PauseScript "scriptID" v214.2.90
恢复任ResumeScript "scriptID" v214.2.90
调用Call Name(args) [-> var]
子程序Sub Name(p...) ... EndSub
条件If ... Then ... Else ... End If
循环While ... End While
重复Repeat n ... End Repeat
标签Label name
跳转Goto label
行跳转GotoLine N v214.2.90
表达式a + b, (x + y) * 2
包含var contains "text"
不包含var notContains "text"
模糊色var ~= "#RRGGBB" [N]