@lisaisacat
2019-06-05T11:07:22.000000Z
字数 119164
阅读 77566
脚本开发
触动精灵是一款模拟手机触摸、按键操作的软件,通过制作脚本,可以让触动精灵代替双手,自动执行一系列触摸、按键操作。触动精灵简单、易用,不需要掌握任何编程知识就可以录制出功能强大的脚本;还可以使用编程知识,编写出功能更为复杂,交互更为灵活的脚本;只要能够在手机上完成的人为操作,触动精灵都可以代替完成,不仅省力,而且高效。
触动精灵采用 Lua 脚本语言作为底层语言,支持 Lua 5.2.3 版本的所有语法与基本函数,并在其的基础上添加了一些扩展函数,用于取色、找色、找图、发送触摸事件等高级功能的实现。
用户在阅读本函数说明前,请参考 Lua 的官方手册以及相关资料,学习以下基本语法:
- 注释
- 变量与类型
- 运算符
- 条件、循环控制
- 函数定义
- 库函数
- ……
本说明仅供初等文化水平以上的、了解计算机编程基本原理的个体学习与参考,并不适用于零基础的编程入门者学习编程基本知识。严禁用于商业以及非法目的,严禁转载、抄袭、未经许可地引用。
为了便于解释和描述,本说明中采用了一些非专业的描述与形容方法(如:整数型),敬请理解。因编写校对仓促,如有错误欢迎及时指正,本文中的示例仅供函数参考,不要直接用于脚本中。
重要提示:
Lua 官方手册:http://www.lua.org/manual/5.2/
Lua 中文开发手册:http://book.luaer.cn/
Lua 基础简明教程:https://zybuluo.com/lisaisacat/note/636399
触动精灵的脚本开发、存储过程必须使用 UTF-8 文本编码,如果您出现脚本中文无法正常显示与处理,请在您使用的编辑器或 IDE 中设置文本编码为 UTF-8,谢谢。
- 在学习脚本开发之前,首先要具备一些关于 iOS 越狱和安卓 root 的知识,以及触动精灵的常用信息
- 文档链接:https://www.zybuluo.com/lisaisacat/note/324664
- 看了上面的文档,你可以具备以下知识:
- 什么样的手机适合用来做脚本开发
- 拿到一台越狱手机之后应该做什么才能避免白苹果和报错
- Cydia 不见了或者已安装界面空白该怎么办
- 为什么安装插件总是报错呢
- 首先你需要了解 Lua 这门语言的一些基础知识,什么是循环,什么是函数,布尔型和数值型分别是什么意思,才有可能看得懂下面的教程和手册。
- 文档地址:https://www.zybuluo.com/lisaisacat/note/636399
- 新手在学习使用触动精灵开发脚本的时候,总会进入一些误区,或者会有一些迷惑的点,觉得无从下手,本文总结了一些自己在学习过程中遇到的问题和经验技巧,欢迎大家一起交流分享。
- 文档链接:https://zybuluo.com/lisaisacat/note/508345
- 看了上面的文档,你可以具备以下知识:
- 透明背景图、动图、带动画的界面应该怎么取色
- 找色和找图哪个更好用
- 函数封装是什么
- 脚本报错了怎么办
- 如果你没有任何编程基础,可以先看一下零基础教学视频:https://www.zybuluo.com/lisaisacat/note/585252
- 看了上面的文档,你可以具备以下知识:
- deb 插件安装方法
- 平刷插件 Cydia Eraser
- SSH 命令工具 putty
- 触动精灵的安装使用及常识
- 抓色器和编辑器的使用及常识
- 同样的脚本为什么有的手机运行异常
- showUI 返回值的调用
- showUI 应该怎么写才简洁好用
- 大漠字库工具的用法
- 由于触动精灵在线文档数量较多,很多人不知道如何查询,现建立此文档做为索引,其中会补充一些软件使用的常用信息。
- 触动精灵旗下目前有四款软件:触动精灵(iOS/Android)、小精灵(iOS/Android)、企业版(iOS/Android 开发中)。
- 触动精灵适合开发者和有中控开发能力的工作室使用
- 小精灵适合有图标和包名自定义需求的开发者和工作室使用
- 企业版适合有批量控制设备需求的工作室使用
- 文档地址:https://www.zybuluo.com/miniknife/note/509515
产品名称 | 自定义图标 | 录制 | 调试 | 运行源码 | 授权 | 批量控制 | 支持平台 | 开发者平台 |
---|---|---|---|---|---|---|---|---|
触动精灵iOS | × | √ | √ | √ | 30元/台/年 | 购买API自行开发 | iOS/Android | http://www.touchsprite.net/site/index |
触动精灵安卓 | × | √ | √ | √ | 免费 | 购买API自行开发 | iOS/Android | http://www.touchsprite.net/site/index |
触动小精灵 | √ | × | × | × | 11元/台/月 | 购买API自行开发 | iOS/Android | http://app.touchsprite.net/ |
触动企业版 | × | × | × | √ | 38元/台/年 | 免费 | iOS/Android | http://ent.touchsprite.net/ |
在文档右侧栏顶部点击文档分类菜单栏按钮,即可查看触动精灵所有在线文档。
工欲善其事,必先利其器,在学习触动精灵脚本编写前我们需要下载安装一些辅助工具来完成脚本编写,包含但不限于以下工具:
使用教程:https://www.zybuluo.com/miniknife/note/307627
官方源地址:http://apt.touchsprite.com
测试源地址:http://apt-test.touchsprite.com
脚本存放路径:/var/mobile/Media/TouchSprite/lua
默认资源路径:/var/mobile/Media/TouchSprite/res
脚本日志路径:/var/mobile/Media/TouchSprite/log
配置文件路径:/var/mobile/Media/TouchSprite/config
注意事项
- 有些函数不支持低版本触动精灵,请仔细阅读函数说明并尽量保持触动精灵客户端为最新版。
- 测试版为不稳定版本,为避免不必要的麻烦,请勿大规模安装。
- 测试版和正式版的 Bundle ID 不同,不能跨源覆盖安装或直接升级,请卸载之后再安装另一个源的版本。
支持函数自动补全、函数提示、关键字高亮、文件传送、远程运行、自动缩进等常用功能,已内置所有至最新 2.3.6 版本触动精灵扩展函数,推荐使用。
下载地址:http://www.touchsprite.com/tools
使用手册:https://www.zybuluo.com/miniknife/note/123055
视频教程:https://www.zybuluo.com/lisaisacat/note/324664#编辑器与抓色器的使用
一个趁手的抓色器可以让你的脚本开发过程变的轻松愉快,在此强烈推荐由苏泽制作的触动抓色器,快捷抓点、一键生成代码、远程抓屏,让你如虎添翼。具体使用方法请阅读压缩包内附带的说明(远程抓屏功能需使用触动精灵iOS v2.1.5 以上版本)。
下载地址:http://www.touchsprite.com/tools
使用手册:https://www.zybuluo.com/havonz/note/94681
视频教程:https://www.zybuluo.com/lisaisacat/note/324664#编辑器与抓色器的使用
猩猩模拟器、海马玩模拟器、夜神模拟器、逍遥模拟器、51 模拟器、雷电模拟器
模拟器使用教程:https://www.zybuluo.com/miniknife/note/443336
从系统兼容和资源占用角度考虑,推荐使用猩猩模拟器。
参数 | 类型 | 说明 |
---|---|---|
index | 整数型 | 手指序号(可省略) |
x,y | 整数型 | 屏幕坐标 |
脚本实例:
快速划动
touchDown(150, 550); --在坐标 (150, 550)按下
mSleep(30);
touchMove(150, 600); --移动到坐标 (150, 600),注意一次滑动的坐标间隔不要太大,不宜超过50像素
mSleep(30);
touchUp(150, 600); --在坐标 (150, 600) 抬起
连续划动
touchDown(150, 550); --在坐标 (150, 550) 按下
for i = 0, 400, 10 do --使用for循环从起始点连续横向移动到终止点
touchMove(150 + i, 550);
mSleep(10); --延迟
end
touchUp(150 + 200, 550); --在坐标 (350, 550) 抬起
多点触控
touchDown(1, 200, 400); --手指 1 在坐标 (200, 400) 按下
touchDown(2, 300, 500); --手指 2 在坐标 (300, 500) 按下
mSleep(50);
for i = 1, 100, 1 do --使用 for 循环使两只手指同时分离
touchMove(1, 200 - i, 400 - i);
touchMove(2, 300 + i, 500 + i);
mSleep(10);
end
touchUp(1, 200 - 100, 400 - 100); --抬起手指1
touchUp(2, 300 + 100, 500 + 100); --抬起手指2
封装一个点击函数
function click(x, y)
touchDown(x, y)
mSleep(30)
touchUp(x, y)
end
click(100, 200) --点击坐标 100,200 位置
方形渐开线
init(1)
mSleep(1000)
local x = 1010 --起始坐标x
local y = 698 --起始坐标y
local v = 30 --两点间距离
touchDown(x, y)
mSleep(100)
for var = 1,20 do
j = 0
k = v
for _i = 1,2 do
for i = 1,10 do
x = x + j
y = y + k
touchMove(x, y)
mSleep(20)
end
j = v
k = 0
end
v = v * (-1.05)
end
touchUp(x, y)
圆形渐开线
init(1)
mSleep(1000)
local x0 = 1010 --起始坐标x
local y0 = 698 --起始坐标y
local rr = 20 --设置递增半径
local l = 10 --设置点间距
local p = 0 --初始化角度
local r = 30 --设置首圈半径
local rn = 10 --设置圈数
touchDown(x0, y0)
mSleep(100)
for var = 1,rn do
while p < math.pi * 2 do
x = x0 + r * math.cos(p)
y = y0 - r * math.sin(p)
touchMove(x, y)
mSleep(10)
p = p + l/r
end
p = 0
r = r + rr
end
touchUp(x0, y0)
注意事项:
- 需要注意的是在使用
touchDown
、touchMove
、touchUp
函数时,中间一定要插入一定的延时,建议大于 20 毫秒,否则可能会出现点击无效等异常情况。- 使用滑动函数时,新手常犯的错误就是两点之间滑动距离过大,请注意
touchDown
、touchMove
的坐标间隔不宜超过 50 像素。- 非多点触控可省略手指 id
- 新手使用点击、随机点击、直线或角度滑动等相关函数请参考函数扩展库
- 在部分安卓应用程序中的HTML5页面中,出现脚本能够点击,但点击没有后续反应的问题。此问题目前可以通过以下写法来解决:
os.execute("input mouse tap x y"),其中 x y 为坐标值
名词解析:
- 手指序号,用于多点触控的支持。标记多只手指,来分别控制它们的移动。
- 屏幕坐标,横坐标为 x,纵坐标为 y,单位为像素。例如,iPhone 4 与 iPhone 4S 的屏幕分辨率 为 640 * 960,则其最大横坐标为 640,最大纵坐标为 960。
- for 循环是 Lua 基本语法,属于循环控制。
返回值 | 类型 | 说明 |
---|---|---|
x,y | 整数型 | 用户点击屏幕的坐标 |
ret | table型 | 当touchCound参数有效时,将返回一个包含所有点击坐标的table |
参数 | 类型 | 说明 |
---|---|---|
touchCount | 整数型 | 所需获取的 点/坐标 个数(需引擎版本 iOS v2.2.4,Android v1.1.9以上支持) |
脚本实例:
dialog("一秒后接收用户一次点击", 0);
mSleep(1000);
x,y = catchTouchPoint();
dialog("x:"..x.." y:"..y, 0);
--获取多个点击坐标
ialog("一秒后接收用户三次点击", 0);
mSleep(1000);
local ret = catchTouchPoint(3);
for i = 1, #ret do
dialog("第"..i.."次点击的位置:"..i..",x="..ret[i].x..",y="..ret[i].y);
end
注意事项:
- 部分安卓模拟器不支持该函数。
- 此函数将阻止脚本继续运行, 一直等待用户完成屏幕点击。
- 此函数获取到的坐标为竖屏坐标,横屏情况请自行转换。
- 本函数有较小的延迟,连续点击时,请勿点击过快。
- 在 iOS 引擎版本 v2.2.4 以上中可接收多个点击坐标并以 table 形式返回。
init(0) -- iOS 设备以 Home 键在下方时的屏幕左上角为坐标系原点(0,0),iOS 7 以上系统有效;安卓设备以当前屏幕默认截图方向进行初始化
init(1); --iOS 设备以当前应用 Home 键在右边初始化,即以 Home 键在右侧时的横屏左上角为屏幕坐标原点(0,0);安卓设备以屏幕默认截图方向向左旋转90°进行初始化
注意事项:
- 安卓系统不同设备初始的截图方向有所不同,编写脚本前请用截图函数确认设备的默认方向。
- iOS6 系统如果填写 bid 参数的话,请在使用 runApp 函数之后再使用此函数,才能获取到正确的当前应用坐标系。
- 此函数可在脚本运行过程中多次调用已改变屏幕方向。
- 如在脚本中未指定屏幕方向,系统将默认为竖屏或初始方向。
参考资料:
Bundle ID 的获取方法
1. 在触动精灵客户端的 更多 -> 应用ID查询 中能查看到应用程序的 Bundle ID;
2. iOS 使用 iFile、PP助手等软件可查看应用文件夹下的 Info.plist,其中的 CFBundleIdentifier 即为该应用的 Bundle ID。
3. 使用 frontAppBid 函数,前台运行要获取 Bundle ID 的应用,运行此函数并用 diolag、toast、nLog 函数显示返回值。
返回值 | 类型 | 说明 |
---|---|---|
orient.app | 整数型 | 前台应用方向 |
orient.dev | 整数型 | 手机屏幕方向 |
脚本实例:
local orient = getDeviceOrient()
dialog("屏幕方向:" .. orient.dev .. "\n应用方向:" .. orient.app, 0)
注意事项:
屏幕方向,0-3,和 init 方向一致
该函数获取时间长,不建议频繁调用,否则可能会影响脚本效率
参数 | 类型 | 说明 |
---|---|---|
rotate | 整数型 | 0 - 竖屏;1 - Home键在右边;2 - Home键在左边 |
返回值 | 类型 | 说明 |
---|---|---|
width | 整数型 | 获取到的屏幕宽度 |
height | 整数型 | 获取到的屏幕高度 |
脚本实例:
根据分辨率判断脚本是否适配
width, height = getScreenSize();
if width == 640 and height == 1136 then --iPhone SE, 5, 5S, iPod touch 5
dialog("iPhone SE, 5, 5S, iPod touch 5")
elseif width == 640 and height == 960 then --iPhone 4,4S, iPod touch 4
dialog("iPhone 4,4S, iPod touch 4")
elseif width == 320 and height == 480 then --iPhone 非高分屏
dialog("iPhone 非高分屏")
elseif width == 768 and height == 1024 then --iPad 1,2, mini 1
dialog("iPad 1,2, mini 1")
elseif width == 1536 and height == 2048 then --iPad 3,4,5, mini 2
dialog("iPad 3,4,5, mini 2")
elseif width == 1080 and height == 1920 then
dialog("小米 4,华为荣耀 6p 等")
elseif width == 720 and height == 1280 then
dialog("红米 note2 等")
elseif width == 768 and height == 1280 then
dialog("魅蓝等")
elseif width == 800 and height == 1280 then
dialog("三星 N5100 等")
elseif width == 480 and height == 800 then
dialog("酷派 8017-T00 等")
end
注意事项:
- 统一为 iOS 竖屏(Home 键在下方时)、安卓初始方向屏幕的宽度和高度。
- 部分安卓设备存在无法获取到屏幕分辨率的问题,需要在脚本中判断如果返回值小于0则指定一个固定的宽高。
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | true - 打开,false - 关闭 |
width | 数值型 | 基准屏幕的宽度 |
height | 数值型 | 基准屏幕的高度 |
脚本实例:
setScreenScale(true, 750, 1334) --以750,1334分辨率为基准坐标进行缩放
--[[
当此函数打开时,将影响点击、取色、单点模糊找色函数
]]
setScreenScale(false) --关闭缩放
注意事项:
- 当此函数打开时,受影响的函数为点击和单点找色函数:
touchDown
touchUp
touchMove
getColor
getColorRGB
findColorInRegionFuzzy
snapwot
- 多点找色函数不受此函数影响
- 当两个设备宽高比相差较大时,此函数转换后的效果较差
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 保持开关 |
脚本实例:
遍历屏幕区块
keepScreen(true); --打开保持屏幕,当参数为 true 时启用屏幕保持,运行到该函数时内存中的屏幕图像保持在这一时刻
for k = 1, 640, 10 do
for j = 1, 960, 10 do
--格式化为十六进制文本
color = string.format("%X", getColor(k, j));
--输出到本地日志
nLog("("..k..", "..j..") Color: "..color..".");
end
end
keepScreen(false); --关闭保持屏幕,当参数为 false 时关闭屏幕保持,释放内存中的屏幕图像,以备下一次继续保持。
注意事项:
- 据不完全统计,与不使用该函数相比,使用此函数会使普通屏上脚本取色速率提升 100 倍,高分屏上脚本取色速率提升 50 倍。在执行大量静态图像操作时,请务必使用该函数优化脚本性能。
- 该函数一般用于画面变动节奏较慢,但需要根据大量取色、找色来完成计算和操作的脚本中,例如"天天爱消除"、"天天星连萌"这样的游戏。
名词解析:
- 静态图像处理,指可在某一状态下屏幕内容保持到内存(不影响显示),对其进行进一步的 多次分析。否则,每次使用图像类函数,都将截取一次屏幕内容。
- 保持开关,逻辑型只有两种属性:true 为真,false 为假。
注意事项:
- 当使用 keepScreen(true); 时启用屏幕保持,运行到该函数时内存中的屏幕图像保持在这一时刻。
- 当使用 keepScreen(false); 时关闭屏幕保持,释放内存中的屏幕图像,以备下一次继续保持。
参数 | 类型 | 说明 |
---|---|---|
x,y | 整数型 | 将获取颜色值的屏幕坐标 |
返回值 | 类型 | 说明 |
---|---|---|
color | 整数型 | 该点的十进制颜色值RGB |
color_r, color_g, color_b | 整数型 | 该点颜色的RGB值 |
脚本实例:
如果某点符合某颜色则点击
color = getColor(100, 100); --获取(100,100)的颜色值,赋值给color变量
if color == 0xffffff then --如果该点的颜色值等于0xffffff
touchDown(100, 100); --那么点击该点
mSleep(30);
touchUp(100, 100);
end
--亦可写作
if getColor(100, 100) == 0xffffff then
touchDown(100, 100);
mSleep(30);
touchUp(100, 100);
end
如果某点的颜色与某颜色相似则点击
r,g,b = getColorRGB(100,100); --获取(100, 100)的颜色值,赋值给color变量
if r > 200 and g < 150 then --如果红色强度大于 200,绿色强度小于 150
touchDown(100,100); --那么点击该点
mSleep(30);
touchUp(100,100);
end
封装一个单点模糊比色函数
function isColor(x,y,c,s) --封装函数,函数名 isColor
local fl,abs = math.floor,math.abs
s = fl(0xff*(100-s)*0.01)
local r,g,b = fl(c/0x10000),fl(c%0x10000/0x100),fl(c%0x100)
local rr,gg,bb = getColorRGB(x,y)
if abs(r-rr)<s and abs(g-gg)<s and abs(b-bb)<s then
return true
end
end
--下面为函数用法
if isColor(963, 961, 0x7b593f,90) then --90 为模糊值,值越大要求的精确度越高
touchDown(963, 961)
mSleep(50)
touchUp(963, 961)
end
多点模糊比色
在实际游戏脚本制作中,很多界面单靠 1 个点不容易进行准确的判断,这里封装一个配合TABLE使用的多点模糊比色函数来实现精确判断:
function multiColor(array,s)
s = math.floor(0xff*(100-s)*0.01)
keepScreen(true)
for var = 1, #array do
local lr,lg,lb = getColorRGB(array[var][1],array[var][2])
local r = math.floor(array[var][3]/0x10000)
local g = math.floor(array[var][3]%0x10000/0x100)
local b = math.floor(array[var][3]%0x100)
if math.abs(lr-r) > s or math.abs(lg-g) > s or math.abs(lb-b) > s then
keepScreen(false)
return false
end
end
keepScreen(false)
return true
end
--用法
g_t_Table = {
{ 1962, 52, 0xefdccf},
{ 2150, 50, 0xefd8d0},
{ 1964, 76, 0xe9d1c5},
{ 2152, 74, 0xefdcd1},
{ 2122, 62, 0xf1ddd1},
{ 2146, 1080, 0x893824},
{ 1840, 1082, 0x593724},
}
if multiColor(g_t_Table,90) then
touchDown(100,100)
mSleep(50)
touchUp(100,100)
end
名词解析:
- 参数 s 为模糊度,范围 0 - 100,一般使用90即可。
- 实例中的 TABLE 格式可使用触动精灵抓色器生成。
注意事项:
参考资料 如何获取屏幕上某点的颜色
- 在你想在设备上截图,iOS 同时按下
电源键
和Home 键
,安卓为电源键
和音量键-
即可进行截图(此时屏幕会闪一下)。- 使用触动精灵抓色器(http://www.touchsprite.com/tools)可方便的获取所需坐标点的颜色信息,推荐使用。
常见颜色表:http://www.114la.com/other/rgb.htm
名词解析
- R,G,B值,即代表红(Red)、绿(Green)、蓝(Blue)三个通道的颜色强度。
- 整型,指的是可以用十、十六、八进制指定的数据类型。使用十六进制符号,必须加上 0x。
- 赋值是 Lua 基本语法,操作符为"="(一个等号)。
- 等于是 Lua 基本语法,属于条件控制,操作符为"=="(两个等号)。新手常常将等于写作赋值,从而导致编译出现错误。
参数 | 类型 | 说明 |
---|---|---|
color | 整数型 | 将要找的十六进制颜色值 |
degree | 整数型 | 寻找精度,范围:1 ~ 100,当是100时为完全匹配 |
x1,y1 | 整数型 | 欲寻找的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲寻找的区域右下角顶点屏幕坐标 |
返回值 | 类型 | 说明 |
---|---|---|
x,y | 整数型 | 找到的点坐标,如未找到则返回 -1,-1 |
脚本实例:
1.精确寻找指定区域中,指定颜色的坐标,并按下
--寻找符合条件的点
x, y = findColorInRegionFuzzy(0x112233, 100, 50, 50, 300, 300);
if x ~= -1 and y ~= -1 then --如果在指定区域找到某点符合条件
touchDown(x, y); --那么单击该点
mSleep(30);
touchUp(x, y);
else --如果找不到符合条件的点
dialog("未找到符合条件的坐标!",0);
end
2.模糊查找指定区域中,尽可能接近指定颜色的点,并按下
for deg = 100, 1, -1 do --使用 for 循环不断降低精确度
x, y = findColorInRegionFuzzy(0xffffff, deg, 50, 50, 300, 300);
if x ~= -1 and y ~= -1 then --如果在指定区域找到某点符合条件
nLog("在模糊度:"..deg.."下找到一个相似的颜色,坐标:"..x..":"..y)
touchDown(x, y); --那么单击该点
mSleep(30)
touchUp(x, y);
break; --并跳出循环
end
end
注意事项:
- 未找到则返回 (-1, -1) ,所以找到时 x, y 均不等于 -1,~= 为不等于操作符,是 Lua 基本语法, 属于逻辑控制。
- 通过不断降低模糊查找精确度的方法在指定区域查找到的不一定是最接近指定颜色的点,该代码应用过程中,建议使用"保持屏幕"减少性能损耗,参见"保持屏幕"一章。
参数 | 类型 | 说明 |
---|---|---|
picpath | 文本型 | 将要寻找的图片文件名((Android 仅支持 png 格式)) |
degree | 整数型 | 寻找精度,范围:1 ~ 100,当是100时为完全匹配 |
x1,y1 | 整数型 | 欲寻找的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲寻找的区域右下角顶点屏幕坐标 |
mask | 整数型 | 忽略的颜色值(透明色) 若无请填 0 |
type | 整数型 | 找图类型,默认不写为 RGB 找图,更多请看注意事项 |
返回值 | 类型 | 说明 |
---|---|---|
x,y | 整数型 | 找到的图片的左上角顶点坐标,如未找到则返回 -1,-1 |
脚本实例:
精确寻找指定区域中,指定图片的位置
--寻找符合条件的图片(假设图片的背景颜色为白色)
x, y = findImageInRegionFuzzy("test_alpha.png", 90, 0, 0, 320, 480, 0xffffff);
if x ~= -1 and y ~= -1 then --如果在指定区域找到某图片符合条件
touchDown(x, y); --那么单击该图片
mSleep(30)
touchUp(x, y);
else --如果找不到符合条件的图片
dialog("未找到符合条件的坐标!",0);
end
注意事项:
- 以下找图几种 type 方式:
type为空-RGB找图,适用于静态画面,找图速度快,兼容性一般
type为1-二值化找图,适用于所有画面,找图速度慢,兼容性好
type为2-二值化找图,适用于静态画面,找图速度快,兼容性好
- Android 仅支持png格式图片。
- iOS 默认图片路径为 /var/mobile/Media/TouchSprite/res,Android 为/mnt/sdcard/TouchSprite/res(参数中无需填写完整路径),自建目录请填写相对路径。
- 忽略的颜色值指将要寻找的图片的背景颜色,即在屏幕画面上不匹配寻找对象的背景颜色。
- 若该函数找图不理想可使用
findImage 高级区域找图
,几种找图方式可配合使用。- 参数 type 为 1 需引擎版本 iOS v2.3.6-7 以上支持,type为 2 需要引擎版本 iOS v2.3.7 以上支持。
参数 | 类型 | 说明 |
---|---|---|
color | 整型 | 欲寻找的参照点颜色 |
posandcolor | 文本型 | 周边点颜色参数 |
degree | 整数型 | 寻找精度,范围:1 ~ 100,当是100时为完全匹配 |
x1, y1 | 整数型 | 欲寻找的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲寻找的区域右下角顶点屏幕坐标 |
返回值 | 类型 | 说明 |
---|---|---|
x, y | 整数型 | 返回符合条件的参照点的坐标,如未找到则返回 -1,-1 |
进阶指导:
当我们使用“区域模糊找色”函数时,常常会因为屏幕上有大量符合指定颜色的点而找不到 需要的坐标。该函数通过在寻找到一个符合指定颜色color的坐标后,进一步确认其周边点坐标的方式,来确定准确目标。例如,现在我们在图像上找到了我们需要的一个按钮,这个按钮的图案是不变的,但是它的整体位置却会在整个屏幕上变化,现在我们想要在脚本运行时得到其坐标。
我们首先找到一个点:
这个点的颜色为 0x181F85,坐标为 (268, 802)。
记录下来,接着找这个按钮上的另外一个点:
这个点的颜色为 0x00BBFE,坐标为 (297, 803),相对于第一个点的坐标为 (29, 1)。 记录下来,接着找这个按钮上的第三个点和第四个点。
第三个点的颜色为 0x0B6BBE,坐标为 (371, 798),相对于第一个点的坐标为 (103, -4)。
第四个点的颜色为 0x150972,坐标为 (333, 811),相对于第一个点的坐标为 (65, 9)。
现在我们找到了需要的三个点:
序号 | 颜色 | 坐标 | 相对坐标 |
---|---|---|---|
1 | 0x181F85 | (268, 802) | (0, 0) |
2 | 0x00BBFE | (297, 803) | (29, 1) |
3 | 0x0B6BBE | (371, 798) | (103, -4) |
4 | 0x150972 | (333, 811) | (65, 9) |
现在我们可以把它写成多点找色的格式了:
--多点找色
--在屏幕上以左上角坐标 (0,0) 和右下角坐标 (639, 959)确定的区域(即全屏)范围内寻找符合偏移范围和颜色的3个坐标点
x, y = findMultiColorInRegionFuzzy(0x181F85, "29|1|0x00BBFE,103|-4| 0x0B6BBE,65|9|0x150972", 100, 0, 0, 639, 959);
dialog(x..","..y, 0)
--另外一种偏色模式,引擎版本 iOS v2.4.1以上支持
--main为参照点0xffffff的偏色,list为周边点的偏色,如果想对每一个周边点单独偏色,在每一个偏色后面加上偏色值即可,如 "0|0|0x1ac819|0x202020"
x, y = findMultiColorInRegionFuzzy(0xffffff,"0|0|0x1ac819,-4|-208|0x18cb76,3|58|0x21cc79", 90, x, y, x0, y0, { main = 0x101010, list = 0x202020 } )
dialog(x..","..y, 0)
那么返回的(x, y)就应该是(268,802)了。即使这个按钮平移了,这个点的坐标变了,也可以寻找到其准确位置。
注意事项:
- posandcolor 参数中的坐标为相对坐标。
- 多点找色的代码可直接用触动精灵取色工具生成,其使用方法参见图文教程。
- 颜色值的十六进制文本中,其顺序为RGB。
- 相对于第一个点的坐标,即用这个点的横坐标、纵坐标分别减去第一个点的横坐标、纵坐标,可以为负数。
- 使用此函数时精度参数设置过低,会导致性能大幅下降。
- 引擎版本 iOS v2.3.6 以上要求包括基准点在内的所有参照点都必须在查找范围之内。
参数 | 类型 | 说明 |
---|---|---|
color | 整型 | 欲寻找的参照点颜色 |
posandcolor | 文本型 | 周边点颜色参数 |
degree | 整数型 | 寻找精度,范围:1 ~ 100,当是100时为完全匹配 |
x1, y1 | 整数型 | 欲寻找的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲寻找的区域右下角顶点屏幕坐标 |
返回值 | 类型 | 说明 |
---|---|---|
point | table类型 | 以 table 形式返回所有符合条件的参照点的坐标,如未找到则返回的table为空 |
返回的 table 为以下形式:
table = {
{x = 100,y = 110},
{x = 200,y = 210},
{x = 300,y = 310},
...
}
脚本实例:
point = findMultiColorInRegionFuzzyExt( 0xcf0000, "-37|3|0x942814,-38|20|0xeba62d,1|54|0xf2b054,28|22|0x8a5707", 90, 97, 220, 903, 701)
if #point ~= 0 then --如返回的table不为空(至少找到一个符合条件的点)
for var = 1,#point do
nLog(point[var].x..":"..point[var].y)
end
end
--另外一种偏色模式,引擎版本 iOS v2.4.1以上支持
--main为参照点0xffffff的偏色,list为周边点的偏色,如果想对每一个周边点单独偏色,在每一个偏色后面加上偏色值即可,如 "0|0|0x1ac819|0x202020"
point = findMultiColorInRegionFuzzyExt(0xffffff,"0|0|0x1ac819,-4|-208|0x18cb76,3|58|0x21cc79", 90, x, y, x0, y0, { main = 0x101010, list = 0x202020 } )
if #point ~= 0 then --如返回的table不为空(至少找到一个符合条件的点)
for var = 1,#point do
nLog(point[var].x..":"..point[var].y)
end
end
注意事项:
- 引擎版本 iOS v 2.3.6 以上版本中要求包括基准点在内的所有参照点都必须在查找范围之内。
参数 | 类型 | 说明 |
---|---|---|
picpath | 文本型 | 将要寻找的图片文件名 |
x1,y1 | 整数型 | 欲寻找的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲寻找的区域右下角顶点屏幕坐标 |
alpha | 整数型 | 匹配精度,此参数值越低匹配精度越高,默认为40000000,此参数可省略 |
返回值 | 类型 | 说明 |
---|---|---|
x,y | 整数型 | 找到的图片的左上角顶点坐标,如未找到则返回 -1,-1 |
脚本实例:
1.精确寻找指定区域中,指定图片的位置
--寻找符合条件的图片
snapshot('test.png',1,1,55,55) --截图到资源文件夹
x, y = findImage("test.png", 0, 0, 120, 480);--在(0,0)到(120,480)寻找刚刚截图的图片
if x ~= -1 and y ~= -1 then --如果在指定区域找到某图片符合条件
toast(x..y); --显示坐标
else --如果找不到符合条件的图片
toast('没有找到图片!');
end
注意事项:
- 此函数推荐与snapshot 截图函数配合使用,成功率较高。
- 匹配精度建议每次加减1000000,此参数值越低匹配精度越高
- 默认图片路径为 /var/mobile/Media/TouchSprite/res(参数中无需填写完整路径),自建目录请填写相对路径。
- 若该函数找图不理想可使用
findimageinregionfuzzy模糊区域找图
,几种找图方式可配合使用。
参数 | 类型 | 说明 |
---|---|---|
picname | 文本型 | 截图保存的文件名 |
x1,y1 | 整数型 | 欲截取的区域左上角顶点屏幕坐标 |
x2,y2 | 整数型 | 欲截取的区域右下角顶点屏幕坐标 |
quality | 数字型 | 仅支持 iOS,当截图格式选为jpg时,可用此参数控制图片质量,此参数值为大于0且小于等于1的值 |
脚本实例:
iOS 示例
snapshot("test.png", 0, 0, 639, 1135); --以test命名进行截图
--全屏截图(iPhone 5, 5S),并以当前日期为文件名保存
current_time = os.date("%Y-%m-%d", os.time());
snapshot(current_time..".png", 0, 0, 639, 1135); --以时间戳命名进行截图
snapshot(current_time..".jpg", 0, 0, 639, 1135, 0.5); --使用jpg格式截图,并设置图片质量为0.5
Android 示例
--全屏截图(以小米 4 为例),并以当前日期为文件名保存
current_time = os.date("%Y-%m-%d", os.time()); --以时间戳命名进行截图
w,h = getScreenSize();
-- 右下角顶点坐标最大为 (宽度最大值-1, 高度最大值-1)
snapshot(current_time..".png", 0, 0, w-1, h-1);
注意事项:
- Android 系统保存图片只支持png格式,不可以设置质量;iOS 系统保存图片的格式可为 bmp, jpg, png,因为 png 是 iOS 中最常见的格式,所以推荐选择 png。
- 截图时,如使用全屏截图,右下角顶点坐标最大为 ((宽度最大值-1, 高度最大值-1),否则 iOS 系统会出现越界错误,安卓系统截出的图会是纯白色的。
- 默认图片路径请使用
userPath
函数获取,具体使用方法请参阅 对应章节,自建目录请填写相对路径,文件相同将会被覆盖- 本文 iOS 实例中 os.date 与 os.time 为 Lua 基本库函数,请查阅附录 Lua 操作系统函数库。
- ".." 为字符串连接操作符,可以将字符串变量、常量连接在一起。
- 本文 iOS 实例中 640 * 1136 为 iPhone 5, 5S 等设备的分辨率,实际使用中请根据运行设备替换为对应值。
- quality 参数仅在引擎版本高于 iOS v2.0.9 时方可使用。
- 当引擎版本高于 iOS v2.2.5-1,Android v2.0.5 时,四个坐标参数省略,默认截取全屏图像。
返回值:整数型 flag
参数 | 类型 | 说明 |
---|---|---|
pictb | Table型 | 需合并图片的文件名列表,支持使用绝对路径 |
path | 文本型 | 生成新图片的文件名,支持使用绝对路径 |
type | 整数型 | 合并类型,0 - 横向合并;1 - 竖向合并 |
quality | 数字型 | 当生成图片格式为jpg时,可控制图片质量,范围[0 - 1] |
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 - 成功;1 - 失败;2 - 失败;3 - 失败 |
脚本实例:
snapshot("1.png",100,100,200,200) --截取屏幕上左上角坐标为 (100,100),右下角坐标为 (200,200) 区域,宽高皆为 100 像素的图片,图片名为 1.png
snapshot("2.png",100,200,200,300) --截取屏幕上左上角坐标为 (100,200),右下角坐标为 (200,300) 区域,宽高皆为 100 像素的图片,图片名为 2.png
snapshot("3.png",100,300,200,400) --截取屏幕上左上角坐标为 (100,300),右下角坐标为 (200,400) 区域,宽高皆为 100 像素的图片,图片名为 3.png
imageOperMerge({"1.png","2.png","3.png"},"4.jpg",0,0.5) --将上面截取的三张图片合成为一张并命名为 4.jpg
注意事项:
- iOS 系统默认图片路径为 /var/mobile/Media/TouchSprite/res,自建目录请填写相对路径
- 当脚本要上传到帮你玩、企业版和小精灵平台时,请使用 userPath 函数代替 /res 之前的目录使之自动获取。
参数 | 类型 | 说明 |
---|---|---|
name | 文本型 | 日志文件名或服务器地址与端口 不带后缀,自动添加.log |
flag | 整数型 | 可选输出方式 |
contents | 文本型 | 日志内容,在该参数中,加入"[DATE]"自动替换为当前可读时间 |
脚本实例:
1.写到本地日志
initLog("test", 0); --初始化日志 test.log,把 0 换成 1 即生成形似 test_1397679553.log 的日志文件
wLog("test","[DATE] Test_1 OK!!!"); --写入日志,日志内容:当前时间 Test_1 OK!!!
mSleep(500); --间隔时间 500 毫秒
wLog("test","[DATE] Test_2 OK!!!");
closeLog("test"); --关闭日志
2.发送服务器日志
initLog("192.168.1.1", 2); --初始化日志,并以异步方式发送;把 2 换成 3 即为同步发送
wLog("192.168.1.1", "[DATE] Test OK!!!"); --将日志发送到 192.168.1.1
closeLog("192.168.1.1"); --关闭服务器连接
3.多日志记录
initLog("test_1", 0); --初始化日志test_1.log
initLog("test_2", 0); --初始化日志test_2.log
wLog("test_1","[DATE] Test_1 OK!!!");
mSleep(500);
wLog("test_2","[DATE] Test_2 OK!!!");
closeLog("test_1");
closeLog("test_2");
注意事项
- flag参数设置为 2 和 3,需要引擎版本 iOS v1.7.0,Android v1.0 及以上版本支持,并需要配合触动精灵日志服务端 使用,要求设备与运行服务端的PC处于同一网段。
- 该函数支持多日志记录,即可以定义并初始化多个日志用于分类存放。
- 此函数一般用于脚本开发阶段,若脚本开发完成,只需注释掉initLog即可。
- 日志的编码为 UTF-8,请使用支持 UTF-8 编码的编辑器查看。
参数 | 类型 | 说明 |
---|---|---|
content | 文本型 | 需要显示的日志内容 |
-- 打开命令行 切换到adb文件目录下 输入 adb logcat -s touchsprite
sysLog("start")
os_type = getOSType()
if os_type == "android" then
sysLog("Android")
else
sysLog("iOS")
end
sysLog("end")
注意事项:
- 该函数将日志输出到系统级日志中,iOS 系统请使用 iTools 或 XCode 查看,Android 系统使用adb工具查看,过滤标识为 touchsprite。
- 当使用同步消息传送时,脚本需等待日志已经到达服务端才继续执行下面的指令。
- 当使用异步消息传送时,调用者在发送消息以后可以不用等待响应,可以接着处理其他任务。 即发送日志无需等待发送完成即可继续执行。
- 注释的操作符形式为 --...... 或 --[[......]] ,可将用于说明的代码写入脚本以便开发时理解。
参数 | 类型 | 说明 |
---|---|---|
content | 文本型 | 需要显示的日志内容 |
脚本实例:
for var = 1,50 do
nLog("[DATE]"..var);--在编辑器的日志输入界面查看
mSleep(100);
end
注意事项:
- 该函数需要脚本编辑器 v1.0.3 以上支持。
- 此函数仅作为调试用途,由触动精灵脚本编辑器发起的脚本运行将会接收到 nLog 回传信息,其他方式运行的脚本将不会触发 nLog 函数。
- 使用该函数无需设置日志接收端 IP 地址。
- 请在编辑器的日志输出面板查看该函数返回的日志信息。
- 当脚本中频繁使用此函数时,由于日志是异步发送的,如果编辑器接收到的日志内容没有按照顺序显示,是正常现象。此问题可以通过在 nLog 之间插入toast 函数解决。
参数 | 类型 | 说明 |
---|---|---|
interval | 整数型 | 单位为毫秒,脚本暂停执行的时间长度 |
脚本实例:
1.延迟1秒和1分钟
mSleep(1000); --延迟1秒钟
mSleep(60 * 1000) --此函数不适合用于长时间的精确计时,如长时间的精确计时请使用 os.time
2.按住 3 秒不松手
touchDown(200, 300); --按下
mSleep(3000); --延迟 3 秒
touchUp(200, 300); --抬起
注意事项:
- 延迟函数的使用与各类函数的使用息息相关,尤其是触摸类函数。脚本一般是用来模拟人在界面上的操作,因此要考虑人在各种情况下的延迟、界面加载时的响应时间。
- 延迟间隔不可过短,当 interval <= 50 ms 时,延迟精确度大幅下降,当 interval <= 16 ms 时,实际延迟约在16 ms左右。
- 请勿将此函数用于长时间的精确计时。
- 1 秒 (s) = 1000 毫秒 (ms)。
脚本实例:
弹出许可协议,若不同意则退出脚本
ret = dialogRet("许可协议\n协议内容", "同意", "不同意", 0, 0);
if ret == 0 then --如果按下"同意"按钮
toast("您选择了同意")
else
toast("您选择了不同意,脚本退出运行")
lua_exit(); --否则退出脚本
end
注意事项:
- 需要注意的是调用该函数时,脚本并非立即终止执行,脚本将会在你调用此函数之后的下一行结束,如果不希望出现此情况可以在调用函数之后加入一行无意义代码即可。
脚本实例:
dialog("重载脚本", 0)
lua_restart()
dialog("执行不到这里", 0)
注意事项:
- 此函数作用相当于停止脚本后重新运行脚本。
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 状态标识 true == 开启来电暂停;false == 关闭来电暂停 |
脚本实例:
luaExitIfCall(true); --当有电话拨入时,检查来电暂停状态标识,若为 true,则立即终止脚本;若为 false,则继续运行脚本[此处输入链接的描述][21]
init(0);
注意事项:
- 该函数在脚本中可使用多次,以调整配置。
- 当有电话拨入时,检查来电暂停状态标识,若为 true,则立即终止脚本;若为 false,则继续运行脚本。
- 引擎版本 iOS v2.2.4 以上版本将停止改为暂停。
返回值 | 类型 | 说明 |
---|---|---|
tsp.type | 文本型 | 返回当前脚本的类型: lua tsp p4u |
tsp.auth | 数值型 | 返回当前脚本的授权状态: 0 - 未授权;1 - 已授权;2 - 试用中 |
tsp.id | 文本型 | 返回当前脚本的ID(此ID唯一,可在开发者平台查看) |
脚本实例:
tsp = checkScriptAuth()
nLog(tsp.type) --输出脚本类型 lua tsp p4u
tsp = checkScriptAuth()
nLog(tsp.id) --输出tspid号,脚本必须为tsp否则返回空值
tsp = checkScriptAuth()
if tsp.auth == 2 then --试用字段 iOS 只支持 v2.4.1,Android v2.2.4 以上版本
dialog("脚本状态:试用中")
elseif tsp.auth == 1 then
dialog("脚本状态:已激活")
else
dialog("脚本状态:未激活")
end
参数 | 类型 | 说明 |
---|---|---|
text | 文本型 | 提示信息,将在设备屏幕上以弹窗形式显示 |
time | 整数型 | 提示信息显示的时间,不限时间请填0 |
脚本实例:
1.欢迎使用
dialog("欢迎使用触动精灵!", 5); --Android 系统在部分设备上需要在系统设置里开启悬浮窗权限方可正常使用此函数
mSleep(1000);
dialog("本脚本仅供演示对话框的用法。\n提示信息可以换行。",0);
注意事项:
- time 参数时间一般在 2 秒以上,否则出现时间太短看不清楚。
- 该函数仅供呈现提示信息给用户,不可接收返回值。
- 该函数所产生的提示窗口显示的时候会影响当前屏幕取色,请在合理的位置使用该函数。
- 关于转义字符:\r\n 为换行,请查阅 Lua 转义字符表。
- 在引擎版本 iOS v2.2.4 以上版本中,
time
参数可省略,如省略将按 0 处理。- 安卓系统在部分设备上需要在系统设置里开启悬浮窗权限方可正常使用此函数。
参数 | 类型 | 说明 |
---|---|---|
text | 文本型 | 提示信息,将在设备屏幕上以HUD形式显示 |
time | 整数型 | 停留时间(单位:秒),当触动精灵版本高于v2.3.0时有效 |
脚本实例:
1.欢迎使用
toast("欢迎使用触动精灵!");
mSleep(3000);-- 建议 toast 函数后面添加 3 秒间隔否则可能显示错误
toast("本脚本仅供演示toast函数效果。\n提示信息可以换行。");
注意事项:
- 该函数所产生的提示信息将以HUD形式显示在屏幕上,该函数所产生的提示信息可能会影响当前屏幕的找色,请合理使用。
参数 | 类型 | 说明 |
---|---|---|
Text | 文本型 | 提示信息 |
cbtn | 文本型 | 默认按钮标题,不需要请填 "" |
btn1 | 文本型 | 可选按钮 1,不需要请填 "" 或 0 |
btn2 | 文本型 | 可选按钮 2,不需要请填 "" 或 0 |
time | 整数型 | 提示信息显示的时间,不限时间请填 0 |
返回值 | 类型 | 说明 |
---|---|---|
choice | 整数型 | 返回用户按下按钮的序号 cbtn == 0;btn1 == 1;btn2 == 2 |
脚本实例:
1.选择性别(双选)
choice = dialogRet("请选择您的性别:", "男", "女", "", 0);
2.选择性别(三选)
choice = dialogRet("请选择您的性别:", "男", "女", "人妖", 0);
if choice == 0 then --男
dialog("你好,帅哥。",0);
mSleep(1000);
elseif choice == 1 then --女
dialog("你好,美女",0);
mSleep(1000);
else --人妖
dialog("人妖不允许使用该脚本。",0);
mSleep(1000);
lua_exit(); --退出脚本
end
3.请阅读许可协议
dialogRet("这里是许可协议或广告,强制阅读 30 秒不可消除。", "", "", "", 30);
注意事项:
- 请勿将三个按钮都设置为空,再将 time 参数设置为 0,这样将造成出现无法消失也没有按钮的 对话框,造成设备无法进行其它操作,只能重启(已在 2.3.6 版本中修复)。
- 值得一提的是,cbtn 总是对话框的最右边或者最下面的按钮。
- 参数中的 0 是数字,不是文本 "0"。
- 当 time 参数不为 0 并且用户没有选择,超时将返回 3。
参数 | 类型 | 说明 |
---|---|---|
title | 文本型 | 提示标题 |
format | 文本型 | 编辑框中浅色的提示文字,如果需要两个编辑框,则将提示文字用"#"分割 |
btn | 文本型 | 确认按钮标题 |
返回值 | 类型 | 说明 |
---|---|---|
text_a,text_b | 文本型 | 返回用户输入的文本 |
脚本实例:
1.输入姓名
::getInfo:: --设置跳转标签
text_a = dialogInput("请输入您的姓名", "在这里输入姓名", "确认");
mSleep(1000);
2.输入姓名和年龄
::getInfo:: --设置跳转标签
text_a, text_b = dialogInput("请选择您的姓名和年龄", "在这里输入姓名#在这里输入年龄", "确认");
text_b = tonumber(text_b) --年龄转化成数字类型
mSleep(1000);
if text_b ~= nil and text_a ~= "" then --均已填写
dialog("你好,"..text_b.." 岁的 "..text_a.." 。", 5);
mSleep(1000);
elseif text_a ~= "" then --只填写了姓名
dialog("你好, "..text_a..",忘记年龄了? 请输入年龄。", 5);
goto getInfo
mSleep(1000);
else --均未填写
dialog("请填写您的信息!", 5);
mSleep(1000);
goto getInfo; --返回重新填写
end
注意事项:
- 一般来说,使用该函数都要对用户输入的数据进行一定的检查,例如要求非空、长度不得少于。
- 使用双编辑框时,函数返回的两个字符串顺序与 format 中的顺序相反,请注意。
- 由于对话框事件需要响应时间,所以建议每次使用对话框,均应使用延迟。
名词解析:
- goto 是 Lua 基本语法,设置标签,然后使用 goto 函数跳转到代码的指定位置向下执行。该函数请谨慎使用,因为大量的跳转会造成代码编写的混乱。
返回值 | 类型 | 说明 |
---|---|---|
time | 整数型 | 返回从 1970年1月1日到当前状态的秒数,如获取失败则返回 0 |
脚本实例:
获取网络时间 & 格式化网络时间
time = getNetTime();
time_year = os.date("%Y",time) --格式化 time 值获取年份
toast(time_year)
mSleep(3000)
time_M = os.date("%m",time) --格式化 time 值获取月份
toast(time_M)
mSleep(3000)
time_D = os.date("%d",time) --格式化 time 值获取日
toast(time_D)
mSleep(3000)
toast(os.date("%Y年%m月%d日",time)) --连起来可以写成这样
mSleep(3000)
toast(os.date("%Y年%m月%d日%H点%M分%S秒",time)) --或这样
获取网络时间并判断脚本过期
origin = 1404439947; --代表北京时间 2014/7/4 10:12:27
origin_text = os.date("%Y/%m/%d %X", origin); --格式化时间
current = getNetTime(); --获取网络时间
current_text = os.date("%Y/%m/%d %X", current); --格式化时间
if origin >= current then
dialog("脚本尚未过期!", 5);
else
dialog("脚本已经过期!\n脚本使用期限:"..origin_text.."\n当前时间:"..current_text, 5);
lua_exit();
end
注意事项:
- 该函数需要网络支持,且根据网络状况有所延迟。
- 当无法正确获取的时候该函数返回0。
参数 | 类型 | 说明 |
---|---|---|
lastname | 文本型 | 联系人姓 |
firstname | 文本型 | 联系人名 |
mobile | 文本型 | 联系人电话号码 |
脚本实例:
addAB = {
{lastname="小",firstname="明",mobile="10080"},
{lastname="小",firstname="红",mobile="10010"},
{lastname="小",firstname="白",mobile="10000"}
}
for _,v in ipairs(addAB) do
addContactToAB(v)
end
脚本实例:添加 100 个号码到手机通讯录
addAB = {}
f = 1
for k = 1860996268,1860996368 ,1 do
addAB[f] = {lastname,firstname,mobile} --通过 f 的值按顺序创建表格
addAB[f].lastname = tostring(k) --生成姓
addAB[f].firstname = tostring(k) --生成名
addAB[f].mobile = tostring(k) --生成电话号码
f = f + 1
end
for _,v in ipairs(addAB) do
addContactToAB(v) --添加到联系人
end
注意事项:
- 批量导入数据量过大的时候,导入过程会比较长。
本模块提供了对 UTF-8 编码的基础支持。 所有的函数都放在表 utf8 中。
除非另有说明, 当一个函数需要一个字节位置的参数时, 都假定这个位置要么从字节序列的开始计算, 要么从字符串长度加一的位置算。 和字符串库一样,负的索引从字符串末尾计起。
参数 | 类型 | 说明 |
---|---|---|
number_(*) | 整数型 | 输入的整数序列 |
返回值 | 类型 | 说明 |
---|---|---|
str | 文本型 | 整数序列转换对应字符串 |
函数用例:
str = utf8.char(35302,21160,31934,28789)
dialog(str, time)
扩展:
- utf8.charpattern字符串用于精确匹配到一个 UTF-8 字节序列的模式
详情参照这里:http://www.runoob.com/manual/lua53doc/manual.html#6.4.1
参数 | 类型 | 说明 |
---|---|---|
str | 文本型 | 输入的字符串 |
返回值 | 类型 | 说明 |
---|---|---|
index | 整数型 | 字符位置(按字节数) |
code | 整数型 | 字符编码 |
函数用例:
str = "触动精灵"
for index,code in utf8.codes(str) do
dialog(string.format("%s的unicode编码为\\u%0x",index,code),time)
end
注意事项:
- 返回字符位置按字节数计算。
- 如果处理到一个不合法的字节序列,将抛出一个错误。
参数 | 类型 | 说明 |
---|---|---|
str | 文本型 | 输入的字符串 |
i | 整数型 | 开始位置,可缺省,默认为1 |
j | 整数型 | 结束位置,可缺省,默认为i |
返回值 | 类型 | 说明 |
---|---|---|
strcode | 整数型 | 字符串中指定位置的字符编码 |
函数用例:
local str = "触动精灵"
strcode = utf8.codepoint (str)
dialog(strcode, time)
注意事项:
- 如果处理到一个不合法的字节序列,将抛出一个错误。
参数 | 类型 | 说明 |
---|---|---|
str | 文本型 | 输入的字符串 |
i | 整数型 | 开始位置,可缺省,默认为1 |
j | 整数型 | 结束位置,可缺省,默认为-1 |
返回值 | 类型 | 说明 |
---|---|---|
length | 整数型 | 字符串中指定位置的字符个数 |
函数用例:
local str = "触动精灵"
length = utf8.len (str)
dialog(length, time)
注意事项:
- 如果处理到一个不合法的字节序列, 返回第一个不合法字节的位置。
参数 | 类型 | 说明 |
---|---|---|
str | 文本型 | 输入的字符串 |
n | 整数型 | 查找的第几个字符 |
i | 整数型 | 开始位置,可缺省 |
返回值 | 类型 | 说明 |
---|---|---|
start_num | 整数型 | 字符串中第n个字符的开始位置 |
函数用例:
local str = "触动精灵"
start_num = utf8.offset (str , 2)
dialog(start_num, time)
注意事项:
- 返回字符位置按字节数计算。
- n 为负数则取在位置 i 前的字符。 当 n 是非负数时,默认的 i 是 1, 否则默认为字符串的长度加一。
- 如果处理到一个不合法的字节序列,将抛出一个错误。
参数 | 类型 | 说明 |
---|---|---|
string | 文本型 | 将输入的文本以及控制字符 |
脚本实例:
输入欢迎文本并发送
touchDown(150,150); --点击输入框获取焦点(假设输入框坐标已知)
mSleep(30)
touchUp(150,150);
mSleep(1000); --延迟 1 秒以便获取焦点,注意某些应用不获取焦点无法输入
for var = 1,15 do
inputText("\b") --删除输入框中的文字(假设输入框中已存在文字)
end
inputText("Welcome.#ENTER#"); --在输入框中输入字符串"Welcome."并回车;此函数在某些应用中无效,如支付宝、密码输入框等位置,甚至可能会导致目标应用闪退
注意事项:
- 使用该函数前,必须先点击输入框获取焦点(指使当前的输入光标停留在某一输入框中)
- 控制字符包括 \b、\n、\r、#ENTER#,如果设备系统版本为 iOS 7,\r无法使用,使用\b需安装引擎版本 iOS v1.6.9 及以上
- 仅在 iOS 7 上可使用"#ENTER#"作为回车,相当于点击虚拟键盘上的 "Done"
- 需要注意的是,并不是所有输入框都可以使用此功能,如支付宝、密码输入框等位置,甚至可能会导致目标应用闪退
- 该函数不支持第三方输入法(指百度输入法、搜狗输入法等),iOS 系统请切换到系统内置输入法,安卓系统在使用该函数时,将自动切换至触动精灵输入法
- 模拟器不能输入的话,需要修改设置,修改教程:http://bbs.touchsprite.com/thread-5203-1-1.html
- 对于弹出的窗口,需要先初始化再使用该函数,例如 App Store登录窗口(该窗口Bundle ID 为"com.apple.springboard")
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 保持开关 |
脚本实例:
-- 需要多次输入的登录模块
function login(...)
switchTSInputMethod(true); -- 切换到触动/帮你玩输入法
-- 点击输入框获取焦点
touchDown(x, y)
mSleep(30)
touchUp(x, y)
inputText("username")
-- 点击输入框获取焦点
touchDown(x, y)
mSleep(30)
touchUp(x, y)
inputText("password")
switchTSInputMethod(false); -- 切换到之前的输入法
end
-- 不需要inputText输入的其他逻辑模块
function main(...)
login()
end
main()
注意事项:
- 点击输入框之前调用
switchTSInputMethod(true)
,结束调用inputText
时调用switchTSInputMethod(false)
,这样不会导致用户手动输入失败或者inputText
输入异常。- 先调动
switchTSInputMethod(true)
,才可以通过switchTSInputMethod(false)
切换回之前的输入法,单纯调用switchTSInputMethod(false)
没有效果。- 猩猩模拟器不支持切换输入法,不切换输入法也可以正常输入。
函数名称:获取当前输入法包名
函数方法 : getInPutMethod();
返回值:文本型 bid
支持版本:触动精灵Android v1.3.0以上
返回值 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 用于切换输入法的包名 |
脚本实例:
频繁输入字符的脚本
-- 脚本启动,获取输入法包名
ipm = getInPutMethod()
-- 切换到触动输入法
os.execute("settings put secure default_input_method com.touchsprite.android/.core.TSInputMethod")
-- 脚本主体
-- 结束脚本前切换回之前的输入法
os.execute("settings put secure default_input_method "..ipm)
注意事项:
- 触动输入法包名: "com.touchsprite.android/.core.TSInputMethod"
参数 | 类型 | 说明 |
---|---|---|
flag | 整数型 | iOS6 及其以下系统 0 ==按下;1 ==抬起; |
脚本实例:
iOS 系统返回主屏幕
pressHomeKey(0); --按下 Home 键
pressHomeKey(1); --抬起 Home 键
Android 系统返回主屏幕
pressHomeKey(); --Android 系统不需要填参数,自动点击抬起
iOS 系统调出后台
pressHomeKey(0); --按一次 Home 键
pressHomeKey(1);
mSleep(30); --短暂延迟
pressHomeKey(0); --再按一次,在 iOS 7 以上版本中使用双击功能可使用函数 doublePressHomeKey
pressHomeKey(1);
3.调出 Siri (iPhone 4S 以上,iOS 6 及以下或触动版本高于v2.3.5)
pressHomeKey(0); --按下 Home 键
mSleep(3000); --按住不放
pressHomeKey(1); --抬起
注意事项:
- 在 iOS 6 系统上,状态标识为 0 时,调用该函数则开始按下 Home 键并按住不放,直到状态标识为 1 时重新调用该函数,抬起 Home 键。
- 在 iOS 7 系统上,状态标识只能填写 0,代表按一次 Home 键,即按下并立即抬起 Home 键的操作(该问题已经在触动v2.3.5中修复)。
- 在 iOS 7 以上版本中使用双击功能可使用函数 doublePressHomeKey ,具体用法请参照对应章节。
脚本实例:
1.双击HOME键打开后台
doublePressHomeKey(); --此函数仅能用于 iOS 7 或以上版本
注意事项:
- 此函数需触动精灵iOS V2.x 以上版本支持
- 此函数仅能用于 iOS 7 或以上版本
参数 | 类型 | 说明 |
---|---|---|
key | 文本型 | 模拟外接键盘的键盘码 |
脚本实例:
--以下为粘贴示例
keyDown("RightGUI")
keyDown("v")
keyUp("v")
keyUp("RightGUI")
--以下为输入小写字母
keyDown("t")
keyUp("t")
--以下为输入大写字母
keyDown("CapsLock")
keyDown("t")
keyUp("t")
keyUp("CapsLock")
--以下为输入数字
keyDown("1")
keyUp("1")
--以下为输入符号
keyDown("LeftShift")
keyDown("1")
keyUp("1")
keyUp("LeftShift")
注意事项:
- 当 inputText 函数在某些输入框内无效时可尝试使用此函数输入字符。
- 每个keyDown都对应一个keyUP,单独使用keyDown有可能发生一些不可预料的问题。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 应用程序的Bundle ID 或包名 |
class | 文本型 | 安卓应用程序的类名(选填) |
type | 整数型 | iOS 系统:可选关闭类型(选填),0 - 关闭应用进程;1 - 关闭后台应用 |
返回值 | 类型 | 说明 |
:----: | :----: | :----: |
flag | 整数型 | 0 == 应用启动成功;非0 == 应用启动失败(如果 == 7 应用不存在) |
脚本实例:
打开 iOS 内置天气应用,然后退出
r = runApp("com.apple.weather"); --启动天气应用
mSleep(10 * 1000);
if r == 0 then
closeApp("com.apple.weather"); --退出天气应用,使用此函数后在后台仍可看到应用程序图标属正常现象,实际进程已不在后台
else
dialog("启动失败",3);
end
关闭 iOS 所有后台应用
closeApp("*",1)--关闭所有后台应用(2.3.5以上版本有效)
注意事项:
- runApp函数需要系统响应时间较长,注意做好延迟或判断。
- iOS 系统使用 closeApp 函数后在后台仍可看到应用程序图标属正常现象,实际进程已不在后台。
- 参数 type 仅在引擎版本 iOS v2.3.5 以上版本有效(参数 type 为1时为模拟双击 Home 键,向上滑动退出应用的效果)。
- 关于 Bundle ID 和包名的获取方法,参见"初始化"一章。
- 安卓应用类名自行百度,游戏不可以通过类名直接启动指定页面,不是所有应用都可以通过此方法启动指定页面。
- 请注意,部分手机不支持通过类名跳转指定页面。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 待检测的应用程序 Bundle ID 或包名 |
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 == 不在前台运行;1 == 在前台运行 |
脚本实例:
监听应用状态
isfront = 1;
while isfront == 1 do --如果应用处于前台则继续
mSleep(3000); --此处放置代码块
isfront = isFrontApp("com.tencent.mqq"); --更新前台状态
end
注意事项:
- Bundle ID 的获取方法参见"初始化"一章。
返回值 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 返回前台应用程序的Bundle ID或包名,若无应用处于前台,则返回空字符串 |
脚本实例:
iOS 系统获取前台应用并初始化
bid = frontAppBid();
init(bid,0);
--亦可写作
init(0);
Android 系统获取前台应用并初始化
bid,class = frontAppBid();
dialog(bid.."\r\n"..class);
检查指定应用是否开启
bid = frontAppBid();
if bid ~= "com.apple.mobilesafari" then
dialog("请打开 Safari 再运行该脚本!", 5);
mSleep(3000);
lua_exit();
end
注意事项:
- Bundle ID 的获取方法参见"初始化"一章。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 需要获取路径的应用程序的 Bundle ID 或包名 |
返回值 | 类型 | 说明 |
:----: | :----: | :----: |
path | 文本型 | 目标应用程序的安装路径 |
脚本实例:
appPath = appBundlePath("com.baidu.map"); --获取"百度地图"安装路径
dialog(appPath,0);
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 需要获取路径的应用程序的 Bundle ID |
返回值 | 类型 | 说明 |
---|---|---|
path | 文本型 | 目标应用程序的数据路径 |
脚本实例:
dataPath = appDataPath("com.baidu.map"); --获取"百度地图"数据路径
if dataPath ~= "" then --如果获取到路径
dialog(dataPath,0);
end
注意事项:
- iOS 8 系统下,并非所有应用都有 data 目录,如返回值为空,说明该应用没有data 目录。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 目标应用程序的Bundle ID 或包名 |
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 - 目标应用未运行;1 - 目标应用运行中 |
脚本实例:
flag = appIsRunning("com.tencent.mqq"); --检测 QQ 是否在运行
if flag == 0 then --如果没有运行
runApp("com.tencent.mqq") --运行 QQ
end
注意事项:
- 此函数将判断目标应用的运行状态,目标应用前台运行或者后台运行返回值都为
1
。
参数 | 类型 | 说明 |
---|---|---|
url | 文本型 | 需要打开的目标网址 |
脚本实例:
调用系统浏览器打开触动精灵官方论坛
openURL("http://www.touchsprite.com");
访问 iOS 系统功能页面
openURL("prefs:root=WIFI"); --打开 wifi 界面
openURL("prefs:root=LOCATION_SERVICES"); --打开定位服务界面
openURL("prefs:root=General&path=VPN"); --打开 VPN 界面
注意事项:
- 默认情况下调用的浏览器为系统默认浏览器。
- 欲打开的目标网址必须以 http:// 开头,一些特殊协议也是支持的,Android 系统如:
sms:
,tel:
,iOS 系统如:mailto://, sms://, tel://, ifile://, cydia:// 等等。
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 - 失败;1 - 成功 |
参数 | 类型 | 说明 |
---|---|---|
path | 文本型 | 所要安装的ipa文件路径 |
bid | 文本型 | 所要卸载的应用程序 Bundle ID |
注意事项:
- 此功能支持在 iOS6 以上版本的系统中使用
- ipaUninstall 函数执行成功后将删除文件系统中的 ipa 文件
- 调用此函数前需确保在目标设备中已安装过 AppSync 插件
返回值:整数型 flag
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 - 失败;1 - 成功 |
参数 | 类型 | 说明 |
---|---|---|
path | 文本型 | 所要安装的ipa文件路径 |
bid | 文本型 | 所要卸载的应用程序的应用包名 |
注意事项:
- 等同于 iOS 的ipaInstall、ipaUninstall函数
返回值 | 类型 | 说明 |
---|---|---|
list | table 型 | 已安装应用的 Bundle ID 或包名列表 |
脚本实例:
bidList = getInstalledApps();
for k,v in pairs(bidList) do
dialog(v)
end
返回的 table 为以下形式:
table = {
"com.touchsprite.andriod",
"com.netease.ddyx.netease",
...
}
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 - 未安装;1 - 已安装 |
参数 | 类型 | 说明 |
---|---|---|
speed | 整数型 | 范围为:[1,50] [-50,-1]区间的整数 |
脚本实例:
changeSpeed(10); --应用加速 x10 倍,加速插件 v1.0.2 及以上版本对部分 u3d 应用有效,旧版仅对 2D 游戏有效
changeSpeed(-10); --应用减速为 1/10
注意事项:
- 此函数仅对当前前台运行应用生效(当参数为 1 时恢复正常速度,<1 为减速,>1 为加速)。
- 此函数需配合额外插件方可正常使用(添加官方测试源:apt-test.touchsprite.com 安装)。
- 加速插件有两个版本,触动精灵 iOS v2.3.9 及以上客户端请安装 v1.0.1。
- 加速插件 v1.0.2 及以上版本对部分 u3d 应用有效,旧版仅对 2D 游戏有效。
- 此函数有可能会被部分应用检测导致封号,请开发者谨慎使用。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 应用程序的包名 |
脚本实例:
cleanApp("com.tencent.mobileqq")--清理QQ数据,cleanApp 函数是调用系统方法,清理之后操作不可逆,请谨慎调用
注意事项:
cleanApp 函数是调用系统方法,清理之后操作不可逆,请谨慎调用。
返回值 | 类型 | 说明 |
---|---|---|
type | 整数型 | 设备类型 0 == iPod Touch;1 == iPhone;2 == iPad;3 == 安卓真机;4 == 安卓模拟器 |
name | 文本型 | 设备类型为模拟器时返回具体模拟器名称,非模拟器时没有该参数。 |
模拟器名称 | 返回值 |
---|---|
逍遥模拟器 | 逍遥 |
海马玩模拟器 | Droid4X |
夜神模拟器 | nox |
猩猩模拟器 | x86 |
猩猩模拟器畅玩版 | klte |
天天模拟器 | ttVM_Hdragon |
脚本实例:
根据分辨率判断设备类型
types = getDeviceType();
if types == 0 then
dialog("当前设备为 iPod Touch")
elseif types == 1 then
dialog("当前设备为 iPhone")
elseif types == 2 then
dialog("当前设备为 iPad")
elseif types == 3 then
dialog("当前设备为安卓真机")
elseif types == 4 then
dialog("当前设备为安卓模拟器"..name,5)
end
返回值 | 类型 | 说明 |
---|---|---|
id | 文本型 | 触动精灵32位设备号 |
脚本实例:
获取设备号并输出到日志
id = getDeviceID(); --帮你玩禁用此函数
toast("Device ID: "..id);
注意事项:
- 该函数返回的并非 udid 或系统设备号,而是触动精灵内部设备号,可用来鉴定设备唯一性。
- 帮你玩开发者平台禁用此函数。
返回值 | 类型 | 说明 |
---|---|---|
str.self | 数值型 | 触动服务内存(仅支持 iOS) |
str.free | 数值型 | 系统空闲内存 |
str.total | 数值型 | 系统总内存 |
脚本实例:
str = getMemoryInfo()
dialog("触动服务占用内存 : "..str.self.."MB;剩余 : "..str.free.."MB;总内存 : "..str.total.."MB", 0)--触动服务内存返回值仅支持 iOS 系统
返回值 | 类型 | 说明 |
---|---|---|
version | 文本型 | 返回的触动精灵引擎版本号或系统版本号如:1.8.5、2.0.6 |
脚本实例:
1.判断版本是否符合要求
tsver = getTSVer(); --获取触动精灵引擎版本
tsint = tonumber(string.sub(tsver, 1, 1)..string.sub(tsver, 3,3)..string.sub(tsver, 5,5));
--转化为数字版本号
sysver = getOSVer(); --获取系统版本
sysint = tonumber(string.sub(sysver, 1, 1)..string.sub(sysver, 3,3)..string.sub(sysver, 5, 5));
--转化为数字版本号
if tsint >= 170 and sysint >= 701 then
init(0);
else
dialog("本脚本不支持您的触动精灵引擎版本或系统版本,请尽快升级!", 5);
lua_exit();
end
名词解析:
- string.sub 为Lua基本函数,属于字符串处理函数库,详情请参阅相关文档。
- tonumber 为 Lua 基本函数,属于类型转换函数库,详情请参阅官方文档。
注意事项:
此函数适用于触动精灵、企业版和帮你玩脚本商城、小精灵客户端,在不同的客户端下运行获取的都是触动引擎版本号而不是客户端版本号。
返回值 | 类型 | 说明 |
---|---|---|
os_type | 文本型 | 返回设备的系统类型 ios、android |
脚本实例:
判断系统是否符合要求
os_type = getOSType(); --获取设备系统版本
if os_type == "android" then --返回值为纯小写字母
dialog("欢迎使用触动精灵安卓版")
else
dialog("欢迎使用触动精灵 iOS 版")
end
注意事项:
- 返回值为纯小写字母
返回值 | 类型 | 说明 |
---|---|---|
retTable.charging | 整数型 | 0 - 未充电;1 - 充电状态 |
retTable.level | 整数型 | 当前设备剩余电量,范围:0 - 100 |
脚本实例:
t = batteryStatus();
if t.charging == 1 then
dialog("正在充电", time)
else
dialog("未充电", time)
end
mSleep(1000)
dialog("剩余电量"..t.level.."%")
注意事项:
- 此函数在安卓模拟器上显示充电状态为电量100。
返回值 | 类型 | 说明 |
---|---|---|
idList[n].id | 整数型 | 进程ID |
idList[n].name | 文本型 | 进程名称 |
脚本实例:
str = getProcess()
text = "设备进程列表 总数 : " .. #str .. "\r\n"
for _,v in ipairs(str) do
text = text .. v.id.." : "..v.name .. "\r\n"
end
dialog(text)
返回值 | 类型 | 说明 |
---|---|---|
ret | 文本型 | 当前安装过触动精灵企业版的设备别名 |
注意事项:
- 此函数仅适用于触动精灵企业版。
返回值 | 类型 | 说明 |
---|---|---|
name | 文本型 | 获取到的设备名 |
参数 | 类型 | 说明 |
---|---|---|
name | 文本型 | 要设置的设备名 |
返回值 | 类型 | 说明 |
---|---|---|
imei | 文本型 | 返回设备 IMEI,设备是模拟器时返回 nil |
脚本实例:
local imei = getIMEI();
if imei == nil and imei == 000000000000000 then
dialog("该设备是模拟器或获取 IMEI 失败");
else
dialog(imei);
end
返回值 | 类型 | 说明 |
---|---|---|
ip | 文本型 | 返回设备网络 IP,不打开 wifi 或者模拟器会显示异常。 |
脚本实例:
-- 不打开 wifi 或者模拟器会显示异常
ip = getNetworkIP();
dialog(ip);
返回值 | 类型 | 说明 |
---|---|---|
brand | 文本型 | 返回设备品牌 |
脚本实例:
brand = getDeviceBrand()
dialog(brand);
返回值 | 类型 | 说明 |
---|---|---|
deviceModel | 文本型 | 返回设备型号 |
脚本实例:
model = getDeviceModel()
dialog(model);
返回值 | 类型 | 说明 |
---|---|---|
cpu | 文本型 | 返回设备 CPU 型号 |
脚本实例:
cpu = getCPUType()
dialog(cpu);
返回值 | 类型 | 说明 |
---|---|---|
uuid | 文本型 | 返回设备 UUID |
脚本实例:
uuid = getUUID()
dialog(uuid);
返回值 | 类型 | 说明 |
---|---|---|
sdPath | 文本型 | 返回设备 SD 卡路径,无 SD 卡时返回 nil |
脚本实例:
local sdPath = getSDCardPath();
if sdPath == nil then
dialog("该设备没有 SD 卡");
else
dialog(sdPath);
end
返回值 | 类型 | 说明 |
---|---|---|
dpi | 数值型类型 | 屏幕密度(每寸像素:120/160/240/320) |
density | 数值型类型 | 屏幕密度(像素比例:0.75/1.0/1.5/2.0) |
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开方向锁定 - true;关闭方向锁定 - false |
脚本实例:
setRotationLockEnable(true); --打开方向锁定
setRotationLockEnable(false); --关闭方向锁定
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开 WiFi - true;关闭 WiFi - false |
脚本实例:
setWifiEnable(true); --打开 Wifi
setWifiEnable(false); --关闭 Wifi
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开蓝牙 - true;关闭蓝牙 - false |
脚本实例:
setBTEnable(true); --打开蓝牙
setBTEnable(false); --关闭蓝牙
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开飞行模式 - true;关闭飞行模式 - false |
脚本实例:
setAirplaneMode(true); --打开飞行模式
setAirplaneMode(false); --关闭飞行模式
返回值 | 类型 | 说明 |
---|---|---|
flag.active | 逻辑型 | true - 打开;false - 关闭 |
flag.status | 文本型 | 连接状态本地化字符串,不同语言下字符串不同(仅支持 iOS) |
脚本实例:
flag = getVPNStatus()
if flag.active then
dialog("打开状态"..flag.status)--flag.status仅支持 iOS 系统
else
dialog("关闭状态"..flag.status)flag.status仅支持 iOS 系统
end
注意事项:
- 如系统中没有已经建立好 的VPN 连接,调用此函数将不会产生任何效果。
- 安卓没有 flag.status 字段。
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开VPN默认连接 - true;关闭VPN默认连接 - false |
注意事项:
- 如系统中没有已经建立好的 VPN 连接,调用此函数将不会产生任何效果。
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开蜂窝网络 - true;关闭蜂窝网络 - false |
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开小圆点 - true;关闭小圆点 - false |
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | 打开减弱动画效果 - true;关闭减弱动画效果 - false |
注意事项:
打开此开关对找色影响很大,请谨慎使用。
返回值 | 类型 | 说明 |
---|---|---|
light | 数值型 | 获取到的屏幕亮度值,范围 0 - 1 |
参数 | 类型 | 说明 |
---|---|---|
light | 数值型 | 要设置的屏幕亮度值,范围 0 - 1 |
参数 | 类型 | 说明 |
---|---|---|
vol | 数值型 | 要设置的设备音量,范围 0 - 1 |
注意事项:
- 此函数将同步改变系统中所有音量。
函数实例:
警报
for var = 1,5 do
vibrator(); --振动
mSleep(1000); --延迟 1 秒
end
注意事项:
- 频繁调用该函数可能会减少电池寿命,请谨慎使用。
- 使用此函数需在系统设置里打开震动选项。
参数 | 类型 | 说明 |
---|---|---|
filename | 文本型 | 音频文件名,支持 mp3、m4a、m4r、ogg、wav |
脚本实例:
playAudio("test.mp3"); --播放 test.mp3
mSleep(10000)
stopAudio(); --停止播放
注意事项:
- 音频文件路径请用
userPath
函数获取,自建目录请填写相对路径。- 如音频放置在默认资源目录,参数中可直接填写文件名。
- 脚本终止将直接导致音频播放终止,如音频文件较长,可使用
stopAudio
终止播放。
脚本实例:
结束并锁定设备
lockDevice();
lua_exit();--Android 不支持此函数
注意事项:
- 无人值守的情况下,使用该函数可减少电池消耗。
返回值 | 类型 | 说明 |
---|---|---|
flag | 整数型 | 0 == 表示设备未锁定;非0 == 表示设备已锁定 |
脚本实例:
判断设备是否锁定
flag = deviceIsLock(); --如果要在设备自启动时解锁屏幕直接使用 unlockDevice 函数即可
if flag == 0 then
dialog("未锁定",3);
else
unlockDevice(); --解锁屏幕
end
注意事项:
- unlockDevice 函数功能是解除当前设备屏幕锁定状态,具体使用方法参照对应章节。
- 以上实例配合定时启动脚本效果显著,需要注意的是,由于此函数无法在设备启动过程中正确判断,如果使用开机自启动功能时请勿直接复制此段代码,如果要在设备自启动时解锁屏幕直接使用 unlockDevice 函数即可。
- 安卓模拟器上此函数可能显示异常。
脚本实例:
解锁设备
flag = deviceIsLock(); --判断屏幕是否锁定
if flag == 0 then
dialog("未锁定",3);
else
unlockDevice(); --解锁屏幕
end--开机自启动请勿使用此段代码,直接使用 unlockDevice 函数即可
注意事项:
- 如您的设备设备了锁屏密码,则此函数仅能唤醒屏幕。
- 以上实例配合定时启动脚本效果显著,需要注意的是,由于此函数无法在设备启动过程中正确判断,如果使用开机自启动功能时请勿直接复制此段代码,如果要在设备自启动时解锁屏幕直接使用 unlockDevice 函数即可。
- 此函数仅支持 iOS7 以上系统。
参数 | 类型 | 说明 |
---|---|---|
tim | 整数型 | iOS 系统:0到5,0是代表永不锁屏,1~5位锁屏时间,单位为分;安卓系统:单位为毫秒,设置为参数的最小近似值,具体情况根据手机不同结果不同。 |
脚本实例:
安卓设置锁屏时间
-- 设置无操作一分钟后锁屏
setAutoLockTime(60*1000)
-- 例如
-- A手机系统选项是 1分钟 2分钟 10分钟 30分钟
-- B手机系统选项是 1分钟 2分钟 3分钟 5分钟 10分钟 30分钟
-- 那么如果设置90*1000(1.5分钟), 则A,B手机都是1分钟后自动锁屏
-- 如果设置240*1000(4分钟), 则A手机是2分钟后自动锁屏,B手机是3分钟后自动锁屏
函数实例:
保持屏幕常亮
while true do
mSleep(30 * 1000); --等待 30 秒
resetIDLETimer(); --重置锁屏计时
end
注意事项:
- 该函数可能会减少屏幕、电池寿命,请谨慎使用。
- while true do ... end 为死循环代码,一般不建议这样使用。除非强行终止运行,否则该脚本不会自动停止。
参数 | 类型 | 说明 |
---|---|---|
x,y,z | 整数型 | 选填,摇动左右、前后角度,不填则默认为轻微幅度摇动 |
time | 整数型 | 选填,摇动持续时间,不填则默认为 500毫秒 |
脚本实例:
shakeDevice() --轻微摇动,持续时间 500 毫秒
shakeDevice(0,0,-3,1000)--仅上下摇动,持续时间 1秒
注意事项:
- 调用此函数时请将目标应用置于前台。
- 本函数为异步代码,在摇一摇的同时会继续执行下面的代码,如需阻塞,请自行添加间隔时间。
- 方向和持续时间参数需 iOS 引擎版本 v2.3.8-1 以上版本支持。
名词解析
x,y,z 对应三维坐标系的三条轴,可为负数,控制本函数向 6 个方向摇动
参数 | 类型 | 说明 |
---|---|---|
size | 文本型 | "640x960" "750x1334" "640x1136" "1125x2001" "1242x2208" "768x1024" "1536x2048" "default" |
脚本实例:
setScreenResolution("640x960") --将当前设备分辨率更改为 640*960,开发者平台禁用此函数
mSleep(10000)
setScreenResolution("default") --恢复当前设备默认分辨率
注意事项:
- 每次打开触动精灵客户端将会自动恢复当前设备的默认分辨率(可在更多中关闭此功能)。
- 开发者可合理利用此函数进行单设备多分辨率脚本适配开发,使用此函数修改分辨率后在实际应用中运行脚本可能会存在点击坐标偏差。
- 执行完此函数需要一些时间生效,如在脚本中使用,请在调用此函数后加入适当的延迟。
- 双击电源键可强制恢复默认分辨率(在脚本运行中或者录制过程中不可用)。
- 此函数仅支持 iOS8 以上设备
Retina
屏幕的设备(如:iPad2、iPad Mini)。- 需要注意的是,如果您的设备是 iPhone6,在系统中将显示模式调整为放大,当前分辨率即为
640x1136
,无需再次使用此函数调整分辨率为640x1136
。- 不推荐将分辨率改为比本身设备默认更高的分辨率,可能会出现无法恢复默认分辨率的问题。
- 在iOS9以上版本中请勿使用此函数,会造成一些不可预料的结果。
- 如您的设备有锁屏密码,请勿使用此函数更改分辨率,会造成无法解锁设备的问题。
- 开发者平台禁用此函数。
警告
此函数不推荐写在脚本中给普通用户使用,推荐仅用于开发者进行多分辨率适配截图使用,如要在脚本中使用请用弹窗提醒用户,如因操作不当造成分辨率无法恢复、无法输入解锁密码等后果由用户自己承担。
参数 | 类型 | 说明 |
---|---|---|
bid | 文本型 | 需要清除的应用程序的 Bundle ID |
脚本实例:
清除前台应用的钥匙串
clearKeyChain(frontAppBid());
注意事项:
- 钥匙串一经清除,不可恢复,请妥善保管您的隐私信息。
名词解析:
- 钥匙串,是iOS提供给应用程序,允许自动记住密码以及重要信息的安全存储数据库,钥匙串一旦清除,该应用中记住的密码等机密信息全部清空。
参数 | 类型 | 说明 |
---|---|---|
x | 浮点型 | 将要伪装位置的经度坐标 |
y | 浮点型 | 将要伪装位置的纬度坐标 |
flag | 整数型 | 当此参数为非 0 时,无需启动目标应用也可持续伪装 |
脚本实例:
a = runApp("com.baidu.map"); --启动百度地图
mSleep(2000);
if a == 0 then --启动成功
fakeGPS(87.1478199292, 43.4912963982);--此函数对部分调用非系统 API 接口的 App (如 Uber)无效,注意经纬度顺序:经度在前,纬度在后
end
--多应用伪装不同坐标,多应用伪装功能需引擎版本 iOS v2.4.0 以上支持
local tab = {}
tab["com.tencent.xin"] = { lat=100.000,lon=100.00} --lat纬度,lon经度
tab["com.tencent.mqq"] = { lat=200.000,lon=200.00}
fakeGPS(tab)
注意事项:
- 多次调用该函数能多次伪装位置,当不带参数执行时将取消伪装功能
- 参数 flag 需需引擎版本 iOS v2.4.0 以上支持 以上版本支持(使用此参数后,重启软件即使不运行触动精灵脚本,也会一直处于伪装状态,直到用户运行该软件后执行fakeGPS()后才可以解除伪装状态)
- 此函数对部分调用非系统 API 接口的 App (如 Uber)无效
- 注意经纬度顺序:经度在前,纬度在后
参数 | 类型 | 说明 |
---|---|---|
path | 文本型 | 需要写入系统相册的图片路径,支持绝对路径 |
脚本实例:
saveImageToAlbum(userPath.."/lua/1.png");
saveImageToAlbum("2.png");
注意事项:
- 图片的格式支持 bmp, jpg, png。
- 如不填写绝对路径时,将默认为文件系统
res
目录下的文件。- 当脚本要上传到帮你玩、企业版和小精灵平台时,请使用 userPath 函数自动获取路径。
参数 | 类型 | 说明 |
---|---|---|
path | 文本型 | 需要写入系统相册的视频路径,支持绝对路径 |
脚本实例:
saveVideoToAlbum(userPath.."/lua/1.mp4");
saveVideoToAlbum("2.mp4");
注意事项:
- 视频的格式支持 mp4, avi, mov。
- 如不填写绝对路径时,将默认为文件系统
res
目录下的文件。- 当脚本要上传到帮你玩、企业版和小精灵平台时,请使用 userPath 函数自动获取路径。
返回值、参数 | 类型 | 说明 |
---|---|---|
string | 文本型 | 写入或读出的剪贴板字符串 |
type | 整数型 | 当 type 为 1 时,string参数为一个图片路径(仅支持引擎版本 iOS v2.3.6以上) |
脚本实例:
从剪贴板中写出到编辑框
string = readPasteboard(); --读出剪贴板内容
mSleep(500); --延迟 0.5 秒
inputText(string); --写出字符串
从文件中读入一行并储存到剪贴板
file = io.open(userPath.."/res/test.txt" ,"r"); --以只读方式打开文件
if file then --如果打开成功
writePasteboard(file:read()); --储存到剪贴板
file:close(); --关闭文件
else
toast("Cannot open: test.txt",0);
end
iOS 系统:粘贴图片
writePasteboard("1.png",1)
keyDown("RightGUI")
keyDown("v")
keyUp("v")
keyUp("RightGUI")
注意事项:
- 该函数将覆盖系统剪贴板,如有重要数据储存在剪贴板请及时备份。
- 参数 type 仅支持引擎版本 iOS v2.3.6 以上。
- 当脚本要上传到帮你玩、企业版和小精灵平台时,请使用 userPath 函数自动获取路径。
脚本实例:
以下实例,当用户在脚本运行过程中按音量键停止脚本,将会触发 beforeUserExit 函数并执行函数体内的语句
function beforeUserExit()
dialog("OK",0)
end
for var = 1,30 do
mSleep(1000)
toast(var)
end
注意事项:
- 函数名必须为
beforeUserExit
才能够被识别,请勿在函数体中使用死循环,否则会造成脚本无法终止或其他不可预料的问题。- 此函数可以被
lua_exit()
、音量键停止
、远程接口停止
触发。- iOS 设备上此函数必须在获取触动精灵授权后方可生效。
参数 | 类型 | 说明 |
---|---|---|
x1, y1 | 整数型 | 欲识别的区域左上角顶点屏幕坐标 |
x2, y2 | 整数型 | 欲识别的区域右下角顶点屏幕坐标 |
language | 整数型 | 语言选择: 0 - 英文/数字; 1 - 中文 (特殊参数请看注意事项) |
list | 文本型 | 识别白名单,设置此参数后,不在白名单中的字符将被忽略 |
返回值 | 类型 | 说明 |
---|---|---|
text | 文本型 | 返回的识别结果 |
脚本实例:
-- 引擎版本 Android v1.3.0之前的版本 language 参数 10 或 20 是英文识别, 非 10 或 20 是中文识别; v2.0 以上版本仅支持 0 =英文/数字, 1 =中文, 不支持 10,20,21 等参数。
recognize = ocrText(20, 120, 200, 140, 0); --OCR 英文识别,注意本函数仅对标准字体识别尚可,非标准字体请自行制作字库配合触动点阵识别函数效果更佳
mSleep(1000);
dialog("识别出的字符:"..recognize, 0);
whitelist = "0123456789-"
a = ocrText(92, 1390, 472, 1464, 10, whitelist)
dialog(a)
注意事项:
- 如果英文普通识别不了,可以尝试如下参数:
0 - 普通识别 灰度二值化
10 - 普通识别 适用于部分存在干扰线背景的文字识别
20 - 适用于部分存在干扰线且深色背景的文字识别
21 - 适用于部分深色背景的文字识别
- 引擎版本 Android v1.3.0之前的版本 language 参数 10 或 20 是英文识别, 非 10 或 20 是中文识别; v2.0 以上版本仅支持 0 =英文/数字, 1 =中文, 不支持 10,20,21 等参数。
- 引擎版本 iOS v2.2.7-3,Android v1.3.0 以上中已集成英文字库,直接调用即可。
- 白名单参数需引擎版本 iOS v2.2.7-3,Android v1.3.0 以上支持。
- OCR(英文数字 eng.traineddata,简体中文chi_sim.traineddata)识别库下载地址:chi_sim.traineddata,eng.traineddata;
- 如需使用中文字库,iOS 系统请将中文字库文件移至手机目录
/Applications/ TouchSprite.app/tessdata
,Android 系统移至/sdcard/TouchSprite/res/tessdata
方可正常使用。- 该函数对非正规字体及有干扰的情况下识别效果不佳,推荐用来识别背景色相对单一的英文及数字。
参数 | 类型 | 说明 |
---|---|---|
dict | 文本型 | 字库名,如:dict.txt 由触动精灵点阵字库工具生成,需放置于触动精灵 res 目录 |
index | 整数型 | 字库标识,由 addTSOcrDict 函数返回值生成 |
x1, y1 | 整数型 | 欲识别的区域左上角顶点屏幕坐标 |
x2, y2 | 整数型 | 欲识别的区域右下角顶点屏幕坐标 |
c0, c1 | 文本型 | 偏色范围,由触动精灵点阵字库工具中获取,需要与制作字库时所设值保持一致,多组偏色用#分割 |
alpha | 整数型 | 精确度,范围 0 - 100 |
str | 文本型 | 想要查找的字符串 |
返回值 | 类型 | 说明 |
---|---|---|
index | 整数型 | 字库标识,由 addTSOcrDict 函数返回值生成,tsOcrText 第一个参数需要用到此值 |
ret | 文本型 | 返回的识别结果 |
x, y | 整数型 | 找到的字符串坐标(字符串左上角点),如未找到则返回 -1,-1 |
脚本实例:
1. 识别屏幕指定区域内的文字
index = addTSOcrDict("dict.txt")--生成的字库文件格式必须为 UTF-8 格式,字库首尾不能包含空行、空格等
ret = tsOcrText(index,962,19,1068,54,"FFFFFF,000000",90)
toast(ret)
--在屏幕上找"弓"字的坐标
index = addTSOcrDict("dict.txt")
x, y = tsFindText(index,"弓",35, 226, 385, 264,"fffbff,737573#FFFFFF,000000",90) --两组偏色
toast(x..","..y)
local tab = {
"00ffffe03ffffff1fffffff3ffffffefffffffffffe03fdfff001f9e7e001f00fc003e01f800fc01f001f803e003e0078007c00f000f0000000c00000000001fff001fffffe1ffffffe7ffffffefffffffffffffffffff003ffffe003f78fc003e01f8007c03f000f807c001f00f8003e01f0007c03e000f007c003e007000380000006@00$比$547$34$31"
}
local indext = addTSOcrDictEx(tab) --加载文字点阵字库
local ret = tsOcrText(indext, 0, 0, 640, 1136, "D9762D , 050901", 90)
注意事项:
- 触动精灵字库工具下载地址和使用手册:https://www.zybuluo.com/miniknife/note/629179
- 本函数为打码点阵识别加强版,突破大漠工具最高识别 11 行像素的限制,更适合高分辨率的移动端脚本开发。
参数 | 类型 | 说明 |
---|---|---|
dict | 文本型 | 字库名,如:dict.txt 由大漠工具生成,需放置于触动精灵 res 目录 |
index | 整数型 | 字库标识,由 addDmOcrDict 函数返回值生成 |
x1, y1 | 整数型 | 欲识别的区域左上角顶点屏幕坐标 |
x2, y2 | 整数型 | 欲识别的区域右下角顶点屏幕坐标 |
c0, c1 | 文本型 | 偏色范围,由大漠工具中获取,需要与制作字库时所设值保持一致,多组偏色用#分割 |
alpha | 整数型 | 精确度,范围 0 - 100 |
str | 文本型 | 想要查找的字符串 |
返回值 | 类型 | 说明 |
---|---|---|
index | 整数型 | 字库标识,由 addDmOcrDict 函数返回值生成,dmOcrText 第一个参数需要用到此值 |
ret | 文本型 | 返回的识别结果 |
x, y | 整数型 | 找到的字符串坐标(字符串左上角点),如未找到则返回 -1,-1 |
脚本实例:
index = addDmOcrDict("dict.txt")--生成的字库文件格式必须为 UTF-8 格式,字库首尾不能包含空行、空格等
ret = dmOcrText(index,962,19,1068,54,"FFFFFF,000000",90)--由于大漠工具的 11 行像素限制,对于较大文字识别效率不高,推荐使用触动字库工具配合触动文字识别函数使用效果更佳
toast(ret)
--在屏幕上找"弓"字的坐标
index = addDmOcrDict("dict.txt")
x, y = dmFindText(index,"弓",35, 226, 385, 264,"fffbff,737573#FFFFFF,000000",90) --两组偏色
toast(x..","..y)
注意事项:
- 该函数完全兼容大漠字库格式,字库由大漠工具生成,由于大漠工具的 11 行像素限制,对于较大文字识别效率不高;
- 字库文件必须放置于触动精灵的
res
目录,加载字库时无需填写绝对路径;- 生成的字库文件格式必须为 UTF-8 格式,字库首尾不能包含空行、空格等;
- 使用 dmFindText 函数需引擎版本 iOS v2.2.4,Android v1.2.8 以上支持;
- 触动精灵 iOS V2.2.7-3 以上客户端方可使用 addDmOcrDictEx 函数加载 table 格式字库。
- 大漠工具下载地址:http://pan.baidu.com/s/1nvybZG9;偏色计算器下载:http://pan.baidu.com/s/1o8pdh8Y 密码:5adu
- 大漠点阵字库制作使用教程:https://www.zybuluo.com/lisaisacat/note/324664#大漠点阵字库制作和应用
返回值 | 类型 | 说明 |
---|---|---|
auth | 整数型 | 0 == 当前设备未授权,有单次30分钟的运行限制;1 == 当前设备已授权,无任何限制 |
脚本实例:
auth = deviceIsAuth(); --帮你玩平台禁用此函数
if auth ~= 0 then
dialog("您的触动精灵客户端已授权",0)
end
注意事项:
帮你玩开平台禁用此函数
返回值 | 类型 | 说明 |
---|---|---|
ret | 整数型 | 0表示没有相同设备号设备在运行,1表示有其他相同设备号设备在运行,-1表示频繁请求,-2表示不是tsp脚本,-3表示获取权限失败。 |
脚本实例:
local t1 = os.time()
function MyGetRunningAccess(...)
t2 = os.time()
-- 每五分钟判断一次
if t2 - t1 >= 5*60 then
t1 = os.time()
-- 如果返回值为1 则有相同设备号脚本在运行 停止当前脚本
if getRunningAccess() == 1 then
lua_exit()
end
end
end
while (true) do
MyGetRunningAccess()
end
注意事项
- 5分钟内只允许判断一次,不要频繁调用影响效率
- 可以直接复制脚本示例代码使用。
返回值 | 类型 | 说明 |
---|---|---|
path | 文本型 | 获取触动精灵、帮你玩脚本商城、企业版、小精灵客户端的用户路径 |
脚本实例:
path = userPath();
path = path.."/script/gameCFG.txt" --设置一个在帮你玩客户端中可保存的文件路径
注意事项:
- 由于在帮你玩脚本商城中每个用户都有独立目录,故提供此函数来获取当前用户的文件目录路径,如果你的脚本需要保存/读取一些信息,请先用此函数获取路径并保存在变量中。
- 触动精灵、帮你玩、小精灵的插件目录、日志目录、资源目录都将生成在此路径下,分别对应 plugin、log、res ,如需在脚本中使用以上目录,请在获取到的字符串后自行拼接。
- 帮你玩脚本商城脚本目录为 /script,其他客户端的脚本目录为 /lua.
返回值 | 类型 | 说明 |
---|---|---|
ret | 整数型 | 0 - 触动精灵;1 - 帮你玩;2 - 企业版;3 - 小精灵 |
参数 | 类型 | 说明 |
---|---|---|
flag | 逻辑型 | true - 显示悬浮按钮,false - 隐藏悬浮按钮 |
本类下所有函数都需要引擎版本 iOS v2.3.9 以上版本支持。
参数 | 类型 | 说明 |
---|---|---|
task | 函数型 | 将该函数加入队列 |
back | 表格型 | 选填,错误回调,当执行任务时发生错误异常,则会回调这个函数并不再抛出 |
返回值 | 类型 | 说明 |
---|---|---|
tid | 整数型 | 协程id,id 可用于结束或是等待一个任务 |
函数实例:
local thread = require('thread')
--处理协程的错误
local thread_id = thread.create(function()
mSleep(1000)
--故意制造的错误
--a()
--抛出异常
thread.throw("协程抛出异常")
return 100
end,{
callBack = function()
--协程结束会调用,不论是错误、异常、正常结束
dialog("协程结束了", 0)
end,
errorBack = function(err)
--协程错误结束,一般是引用空调用,err是字符串
dialog("协程错误了:"..err,0)
end,
catchBack = function(exp)
--协程异常结束,异常是脚本调用了throw激发的,exp是table,exp.message是异常原因
local sz = require('sz')
local json = sz.json
dialog("协程异常了\n"..json.encode(exp),0)
end
})
thread.waitAllThreadExit()--等待所有协程结束,只能用于主线程
参数 | 类型 | 说明 |
---|---|---|
task | 函数型 | 将该函数加入队列 |
back | 表格型 | 选填,错误回调,当执行任务时发生错误异常,则会回调这个函数并不再抛出 |
返回值 | 类型 | 说明 |
---|---|---|
tid | 整数型 | 协程id,id 可用于结束或是等待一个任务 |
函数实例:
--子协程会在协程停止后,自动停止
local thread = require('thread')
local thread_id = thread.create(function()
--创建子协程
local sub_thread_id_1 = thread.createSubThread(function()
mSleep(3000)
--因为sub thread 1比parent thread运行时间短,所以以下代码会被执行
toast("sub thread 1 over",3)
end)
local sub_thread_id_2 = thread.createSubThread(function()
--创建子协程的子协程
local sub_thread_2_sub_thread_1 = thread.createSubThread(function()
mSleep(1000)
toast("sub thread 2,sub thread 1 over",3)
end)
mSleep(6000)
--因为sub thread 2比parent thread运行时间长,所以以下代码实际执行不到
toast("sub thread 2 over",3)
end)
mSleep(4000)
toast("parent thread over",3)
end)
thread.waitAllThreadExit()--等待所有协程结束,只能用于主线程
参数 | 类型 | 说明 |
---|---|---|
tid | 整数型 | 协程id,id 可用于结束或是等待一个任务 |
函数用例:
local thread = require('thread')
local thread_id1 = thread.create(function()
for i=1,10 do
toast("协程1:".. i)
mSleep(1200)
end
end)
local thread_id2 = thread.create(function()
for i=1,10 do
toast("协程2:".. i)
mSleep(2000)
end
end)
mSleep(5000)
thread.stop(thread_id1)--关闭协程1
thread.waitAllThreadExit()--等待所有协程结束,只能用于主线程
参数 | 类型 | 说明 |
---|---|---|
tid | 数值型 | 协程ID |
back | 表格型 | 选填,错误回调,当执行任务时发生错误异常,则会回调这个函数并不再抛出 |
返回值 | 类型 | 说明 |
---|---|---|
ok | 逻辑型 | 成功返回true,失败返回false |
ret | 表格型 | 正确无返回,错误返回错误信息 |
函数用例:
local thread = require('thread')
local thread_id = thread.create(function()
mSleep(1000)
return 100
end)
local ok,ret = thread.wait(thread_id)
if ok then
--正常结束,ret是协程函数的返回值,这里ret=100
toast("wait ok,ret is "..ret)
else
--这里不会被执行
local sz = require('sz')
local json = sz.json
toast("wait thread fail:"..json.encode(ret))
end
参数 | 类型 | 说明 |
---|---|---|
timeout | 整数型 | 超时时间 |
thread_id | 整数型 | 协程ID,如果在协程内,参数省略 |
参数 | 类型 | 说明 |
---|---|---|
thread_id | 整数型 | 协程 ID,如果在协程内,参数省略 |
函数用例:
thread = require("thread")
local thread_id = thread.create(function()
thread.setTimeout(2000)
mSleep(1000)
toast("thread step 1")
mSleep(2000)
toast("thread step 2")
mSleep(3000)
--设置有超时,执行不到这了,会调用catchBack
toast("thread over")
end,{
callBack = function()
--协程结束会调用,不论是错误、异常、正常结束
-- toast("我结束了")
end,
catchBack = function(exp)
--协程异常结束,异常是脚本调用了throw激发的,exp是table,exp.message是异常原因
local sz = require('sz')
local json = sz.json
toast("我异常了"..json.encode(exp))
end
})
mSleep(1000)
thread.clearTimeout(thread_id)
mSleep(2000)
thread.setTimeout(1000,thread_id)
--等待所有协程结束
thread.waitAllThreadExit()
注意事项:
因为主线程结束了协程会全部结束,所以使用该函数可以等待协程都结束再退出
函数功能:创建一个可控制浮动窗口并显示动态内容。
支持版本:引擎版本 iOS v2.3.5,Android v2.0.3 以上
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 用于指定创建窗口的ID |
x1,y1 | 整数型 | 窗口左上角顶点坐标 |
x2,y2 | 整数型 | 窗口右下角顶点坐标 |
type | 整数型 | 1 - 窗口可移动;0 - 窗口不可移动 |
脚本实例:
fwShowWnd("wid",0,0,200,200,1) --显示一个可移动的窗口并指定窗口ID为 wid
注意事项:
- 可同时创建多个浮动窗口。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 用于指定窗口载体的ID |
vid | 文本型 | 用于指定一个文字视图ID |
text | 文本型 | 需要显示的文字内容 |
align | 文本型 | 对齐方式,left - 左对齐;right - 右对齐;centerwenb - 居中 |
textcolor | 文本型 | 文字颜色16进制值,填空字符串默认为黑色 |
backgroundcolor | 文本型 | 视图背景色16进制值,填空字符串默认为透明 |
size | 整数型 | 文字大小,填 0 默认值为15 |
type | 整数型 | 文字类型,0-标准;1-粗体 |
x1,y1 | 整数型 | 窗口左上角顶点坐标 |
x2,y2 | 整数型 | 窗口右下角顶点坐标 |
alpha | 整数型 | 选填参数,透明度 0 - 1,默认为1 |
脚本实例:
fwShowTextView("wid","textid","这是一个文本视图","center","FF0000","FFDAB9",0,20,0,0,200,100,0.5) --显示一个文字视图
注意事项:
- 如需要刷新文本内容,重新调用函数即可。
- 视图坐标相对于窗口顶点 (0,0)。
- 透明度只针对背景颜色,文字不受影响。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 用于指定窗口载体的ID |
vid | 文本型 | 用于指定一个图形视图ID |
picpath | 文本型 | 需要显示的图片的路径,支持绝对路径、网络地址 |
x1,y1 | 整数型 | 窗口左上角顶点坐标 |
x2,y2 | 整数型 | 窗口右下角顶点坐标 |
alpha | 整数型 | 选填参数,透明度 0 - 1,默认为1 |
脚本实例:
snapshot("1.png",400,400,600,500)
mSleep(500)
fwShowImageView("wid","picid","1.png",0,100,200,200) --显示一个图片视图
注意事项:
- 如需要刷新图形,重新调用函数即可。
- 视图坐标相对于窗口顶点 (0,0)。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 需要关闭的窗口载体的ID |
vid | 文本型 | 需要关闭的视图ID |
脚本实例:
fwCloseView("wid","textid") --关闭文字视图
注意事项:
- 如需要关闭所有视图,直接使用 fwCloseWnd 函数关闭窗口即可。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 需要关闭的窗口载体的ID |
脚本实例:
fwCloseWnd("wid") --关闭窗口
注意事项:
- 当使用此函数关闭窗口时,所有此窗口内的视图会同时关闭。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 需要关闭的窗口载体的ID |
返回值 | 类型 | 说明 |
---|---|---|
wndTab.ret | 整数型 | 0 - 失败;1 - 成功 |
wndTab.x,wndTab.y | 整数型 | 窗口左上角定点坐标 |
wndTab.x1,wndTab.y1 | 整数型 | 窗口右下角定点坐标 |
脚本实例:
wndTab = fwGetWndPos("wid")
dialog("窗口获取状态:"..wndTab.ret.."\n".."左上角坐标:"..wndTab.x..","..wndTab.y.."\n".."右下角坐标:"..wndTab.x1..","..wndTab.y1, 2)
注意事项:
- 如果该窗口不存在,会返回 0。
参数 | 类型 | 说明 |
---|---|---|
wid | 文本型 | 用于指定窗口载体的ID |
vid | 文本型 | 用于指定一个按钮ID |
text | 文本型 | 需要显示的文字内容 |
textcolor | 文本型 | 文字颜色16进制值,填空字符串默认为黑色 |
bgcolor | 文本型 | 视图背景色16进制值,填空字符串默认为透明 |
image | 文本型 | 需要显示的图片路径,支持绝对路径 |
size | 整数型 | 文字大小,填 0 默认值为13 |
x1,y1 | 整数型 | 窗口左上角顶点坐标 |
x2,y2 | 整数型 | 窗口右下角顶点坐标 |
返回值 | 类型 | 说明 |
---|---|---|
vid | 文本型 | 返回显示按钮的ID |
脚本实例:
local num = 0
fwShowWnd("wid",100,100,200,500,1)
fwShowTextView("wid","id1","点击:" .. num,"center","FF0000","FFDAB9",15,0,0,0,200,100)
fwShowTextView("wid","id2","闪","center","FFFFFF","0000FF",15,0,300,0,400,100)
fwShowWnd("wida",300,300,500,500,1)
fwShowButton("wida","vid","点我","FFFFFF","FF0000","",15,0,0,100,100)
while (true) do
local vid = fwGetPressedButton()
if vid == "vid" then
num = num + 1
fwShowTextView("wid","id1","点击:" .. num,"center","FF0000","FFDAB9",15,0,0,0,200,100)
if num%2 == 0 then
fwShowTextView("wid","id2","闪","center","FFFFFF","0000FF",15,0,300,0,400,100)
else
fwCloseView("wid","id2")
end
end
end
注意事项:
- 不能拖动按钮控件,只能拖动非按钮控件或主控件
init(0)
toast("创建一个可移动的窗口")
fwShowWnd("wid",0,0,200,200,1) --创建一个可移动的窗口
mSleep(2000)
toast("加载文字")
fwShowTextView("wid","id1","这是一个文本视图","center","FF0000","FFDAB9",15,0,0,0,200,100,0.5)
mSleep(2000)
toast("加载一个截图")
snapshot("1.png",400,400,600,500)
fwShowImageView("wid","id2","1.png",0,100,200,200)
mSleep(2000)
toast("随便移动窗口,5 秒后继续")
mSleep(5000)
tab=fwGetWndPos("wid")
dialog("窗口获取状态:"..tab.ret.."\n".."左上角坐标:"..tab.x..","..tab.y.."\n".."右下角坐标:"..tab.x1..","..tab.y1, 2)
mSleep(2000)
toast("关闭文字视图")
fwCloseView("wid","id1") --关闭文字视图
mSleep(2000)
toast("关闭窗口")
fwCloseView("wid")
参数 | 类型 | 说明 |
---|---|---|
ui_json | 文本型 | 自定义界面json格式字符串调用时字符串需经过压缩与转义 |
返回值 | 类型 | 说明 |
---|---|---|
ret | 整数型 | 1 == 确认输入;0 == 取消输入 |
input_(*) | 文本型 | 返回用户输入的多项数据 |
json 就是一串字符串,在该函数中,我们用它来创建界面上的一系列会使用特定的符号标注的元素:
{}
双括号表示对象
[]
中括号表示数组
""
双引号内是属性或值
:
冒号表示后者是前者的值
所以 {"name": "Michael"} 可以理解为是一个包含 name 为 Michael 的对象,而 [{"name": "Michael"},{"name": "Jerry"}] 就表示包含两个对象的数组。
当然了,你也可以使用 {"name":["Michael","Jerry"]} 来简化上面一部分,这是一个拥有 name 数组的对象。
不管是键或文本型的值都要用双引号引起来,所以上面的代码就是 {"name":"json"}。
为了便于 json 的书写,我们通常使用可读性较强的形式;但是为了便于脚本的调用,我们 需要将 json 进行压缩与转义。将上文中的 json 进行转义后,作为字符串放进 showUI 函数的参 数 ui_json 中,例如:
--[[ret, input_1, input_2, ... = showUI("");]]
ret, input_1, input_2, input_3 = showUI("{\"style\":"
.."\"default\",\"views\":[{\"type\":\"Label\",\"text\":"
.."\"settings\",\"size\":25,\"align\":\"center\",\"color\":"
.."\"0,0,255\"},{\"type\":\"RadioGroup\",\"list\":"
.."\"option1,option2,option3,option4,option5,option6,option7\","
.."\"select\":\"1\"},{\"type\":\"Edit\",\"prompt\":\"Test\","
.."\"text\":\"Custom Text\",\"size\":15,\"align\":\"left\","
.."\"color\":\"255,0,0\"},{\"type\":\"CheckBoxGroup\",\"list\":"
.."\"option1,option2,option3,option4,option5,option6,option7\","
.."\"select\":\"3@5\"}]}");
json 在线校验格式化、压缩转义工具:http://www.bejson.com/
上面的代码看起来有些乱,可能会让新手无所适从,我们换一种形式来写:
w,h = getScreenSize();--此段代码仅供演示用,不可复制粘贴直接运行
MyJsonString = [[
{
"style": "default",
"width": ]]..w..[[,
"height": ]]..h..[[,
"config": "save_111.dat",
"timer": 10,
"views": [
{
"type": "Label",
"text": "设置",
"size": 25,
"align": "center",
"color": "0,0,255"
},
{
"type": "RadioGroup",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "1"
},
{
"type": "Edit",
"prompt": "测试三下",
"text": "默认值",
"size": 15,
"align": "left",
"color": "255,0,0"
},
{
"type": "CheckBoxGroup",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "3@5"
}
]
}
]]
ret, input1, input2, input3 = showUI(MyJsonString);
在上面的例子中可以看到"width"
和"height"
的值我们使用了变量 w,h 这两个变量具体数值由 getScreenSize() 函数提供,这样我们实现了UI界面自动适应屏幕大小,需要在UI中使用动态数据的时候我们还可以使用table的方式来进行构造,这样使用变量的时候可以更加顺手,例如:
local sz = require("sz")
local json = sz.json
local w,h = getScreenSize();
MyTable = {
["style"] = "default",
["width"] = w,
["height"] = h,
["config"] = "save_001.dat",
["timer"] = 10,
views = {
{
["type"] = "Label",
["text"] = "设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,255",
},
{
["type"] = "RadioGroup", --单选框,input1
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",--7个单选项,序号从0开始,即选项1编号为0,选项2编号为1,依此类推
["select"] = "1", --默认选择选项2
},
{
["type"] = "Edit", --输入框,input2
["prompt"] = "请输入一个数字",--编辑框中无任何内容时显示的底色文本
["text"] = "默认值", --界面载入时已经存在于编辑框中的文本
},
{
["type"] = "CheckBoxGroup", --多选框,input3
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",--7个多选项
["select"] = "3@5", --默认选择选项3和选项5
},
{
["type"] = "ComboBox", --下拉框,input4
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",--7个下拉选项,序号从0开始,即选项1编号为0,选项2编号为1,依此类推
["select"] = "1", --默认选择选项2
},
}
}
local MyJsonString = json.encode(MyTable);
ret, input1, input2, input3, input4 = showUI(MyJsonString);--返回值ret, input1, input2, input3, input4
- 以上实例中将table转为JSON需要借助 sz 扩展库实现,触动精灵iOS v2.0,Android v1.0 以上版本中已集成扩展库,扩展库的更多用法请参阅手册"触动精灵苏泽扩展库"。
- 最下面返回值的数量应与代码中的非标签空间总数数量保持一致,否则会造成后面的非标签控件返回值无效。
一个包含所有控件的默认样式UI实例
local sz = require("sz")--写 showUI 前必须插入这一句
local json = sz.json--写 showUI 前必须插入这一句
w,h = getScreenSize();
MyTable = {
["style"] = "default",
["width"] = w,
["height"] = h,
["config"] = "save_01.dat",
["timer"] = 99,
["orient"] = 0,--需引擎版本 iOS v2.2.5以上版本支持,Android 暂不支持
["pagetype"] = "multi",--需引擎版本 iOS v2.2.5,Android v2.1.5 以上版本支持
["title"] = "触动精灵脚本配置",--需引擎版本 iOS v2.2.5,Android v1.2.4 以上版本支持
["cancelname"] = "取消",
["okname"] = "开始",
pages =
{
{
{
["type"] = "Label",
["text"] = "第一页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["type"] = "RadioGroup",
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
["select"] = "1",
},
},{
{
["type"] = "Label",
["text"] = "第二页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["type"] = "Edit",
["prompt"] = "请输入一个字母",
["text"] = "默认值",
["kbtype"] = "ascii",
},
{
["type"] = "Edit",
["prompt"] = "请输入一个数字",
["text"] = "默认值",
["kbtype"] = "number",
},
},{
{
["type"] = "Label",
["text"] = "第三页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["type"] = "CheckBoxGroup",
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
["select"] = "3@5",
},
{
["type"] = "ComboBox",
["list"] = "选项1,选项2,选项3",
["select"] = "1",
["data"] = "子选项1,子选项2,子选项3,子选项4#子选项5,子选项6,子选项7#子选项8,子选项9",
["source"] = "test"
},
{
["type"] = "ComboBox",
["select"] = "1",
["dataSource"] = "test"
},
}
}
}
local MyJsonString = json.encode(MyTable);
retTable = {showUI(MyJsonString)};
for var = 1,#retTable do
nLog(retTable[var]) --输出每一个返回值
end
- 以上实例中使用了两个 ComboBox 控件,并在两个 ComboBox 控件之间建立了数据关联,此控件属性需引擎版本 iOS v2.1.8,Android v1.1.0 以上支持。
- 以上实例中的 title 属性需引擎版本 iOS v2.2.5,Android v1.2.4 以上版本支持。
- 以上实例中的 pagetype 属性需引擎版本 iOS v2.2.5,Android v2.1.5 以上版本支持。
- 以上实例中的 orient 属性需引擎版本 iOS v2.2.5以上版本支持,Android 暂不支持。
- 以上实例中最后对于 showUI 的调用将返回一个table。
上面是调用的例子,但是我们首先我们要设计一个界面,并生成一段json字符串,再进行压缩转义。
我们先看上图界面示例json原来的样子(非脚本代码,不可直接引用),再作解释:
{--此示例仅供演示作用,不可复制粘贴直接运行
"style": "default", "config": "save_111.dat", "width": 400,
"height": 120, "bg": "a.png", "timer": 10, "cancelname": "取消", "okname": "开始",
"views": [
{
"type": "Label",
"text": "设置",
"size": 25, "align": "center",
"color": "0,0,255"
},
{
"type": "RadioGroup",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "1"
},
{
"type": "Edit",
"prompt": "测试三下",
"text": "默认值",
"size": 15, "align": "left",
"color": "255,0,0"
},
{
"type": "CheckBoxGroup",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "3@5"
},
{
"type": "ComboBox",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "1"
},
{
"type": "Image",
"src": "http://www.baidu.com/img/bdlogo.png"
}
]
}
创建一个界面,需要包含 style 与 views 两个主键。
style 表示界面样式,views 数组则包含了界面上的控件。
- default - 默认样式,一般设置为默认即可,所有控件自动排列,每个控件占据一行。
- custom - 自定义样式,当界面样式被指定为这种,则必须指定每个控件的 rect 属性以调整控件的尺寸以及位置,具体参看后面章节。
width 与 height 分别指定了界面的宽和高(像素 pixels),请注意宽度不得低于 400 pixels,高度不得低于 120 pixels。
指定界面的背景图片,相对路径为 res 资源目录,可填写绝对路径。
- okname - 指定底部右侧确认按钮上显示的文字。
- cancelname - 指定底部左侧取消按钮上显示的文字。
需引擎版本 iOS v2.2.5,Android v1.2.4 以上版本支持
- 用于指定UI顶部标题栏文字。
- 引擎版本 iOS v2.3.2 以上在多页模式下可以设置多个标题对应多个页面,以逗号分隔。
属性需引擎版本 iOS v2.2.5,Android v2.1.5 以上版本支持
当指定该属性值为
multi
时,UI可分页显示,左右滑动进行翻页,如不指定该属性,将使用默认的单页模式。
iOS 引擎版本 V2.2.5 及以上版本支持
- 0 - Home键在设备下方
- 1 - Home键在设备右侧
- 2 - Home键在设备左侧
引擎版本 iOS v2.3.5 及以上版本支持
引擎版本 iOS v2.3.5,Android v1.3.0 及以上版本支持
- dot - 小圆点(图形)
- number - 数字显示(文字)
引擎版本 iOS v2.3.5 及以上版本支持
注意事项:
当在 iOS9 以上版本的 iPad 设备上使用 showUI 界面时,务必使用此属性指定正确的屏幕方向,否则将可能出现确定、取消按钮无法点击的情况。
- 如果存在此键名,则用户点击确认时保存配置到指定文件中。
- 如果配置文件存在,调用该界面会自动载入该文件中的配置,如果更新了UI代码后必须要删除旧的配置文件才会正常显示。
- 指定界面在自动配置文件存在的情况下,自动确认UI输入。
- 注意使用此属性必须要设定 config 属性,第一次存储配置文件不存在时,此属性不生效,当配置文件存在时,此属性会在生成UI上进行倒计时,同时用户也可以点击闹钟图标取消倒计时。
- 在脚本UI界面点击闹钟标志则取消倒计时功能。
引擎版本 iOS 2.2.6,Android v1.2.7 及以上版本支持
- default - 默认模式,保持旧版格式,可使用此属性兼容旧的脚本UI。
- array - 数组模式,将所有控件返回值按添加顺序放入一个table中并返回。
- table - table模式,将所有控件返回值以 key,values 形式的table返回,key为控件id属性所指定的值。
引擎版本 iOS V2.2.7 及以上版本支持
引擎版本 iOS 2.2.6,Android v1.2.4 及以上版本支持
当 showUI 全局属性 style 为 default 时,如需将多个控件放入同一行显示,可用此属性调整控件宽度。
引擎版本 iOS 2.2.6,Android v1.2.5 及以上版本支持
当此属性为 1 时,将指定下一个控件不换行,用于将多个控件放入一行显示。
我们可以看到,界面控件被定义在 views 数组中。而自定义界面一共有七种控件类型 type:标签 Label,单选框 RadioGroup,编辑框 Edit,多选框 CheckBoxGroup,下拉框 ComboBox,图片 Image。
一共有四种属性:标题 text、字体大小 size、对齐方式 align、字体颜色 color
参数 | 类型 | 说明 |
---|---|---|
标题 text | 文本型 | 必填,一般来用显示说明文字或者标题,该控件没有任何返回值,只用作显示 |
字体大小 size | 数值型 | 选填,如果不指定该属性,则默认值为 15 |
对齐方式 align | 文本型 | 选填,默认左对齐。可取值为:左对齐 left,右对齐 right,居中 center |
字体颜色 color | 文本型 | 选填,默认黑色。使用RGB十进制数值,以英文半角逗号分割 |
注意事项:
标签可支持多行显示,在字符串中插入 \n 可以进行换行,例如:\"测试\n测试 1\n测试 2\"(安卓系统 \n 需写成 \r\n)
文字颜色尽量选择和背景区别较大、在电子设备屏幕上看起来不刺眼的颜色,具体可参考配色网。
一共有五种属性:可选项目标题 list、默认选中项编号 select、控件ID id、在可选项上显示图片 images、选项图片缩放 scale
参数 | 类型 | 说明 |
---|---|---|
可选项目标题 list | 文本型 | 必填,多个可选项目之间用英文半角逗号分割 |
默认选中项编号 select | 文本型 | 必填,只允许填写一个,序号从 0 开始,与可选项目标题中的顺序保持一致 |
控件ID id | 文本型 | 选填,为控件指定ID,可以理解为控件的名称,在返回类型为table时将作为返回table中的key |
在可选项上显示图片 images | 文本型 | 选填,此属性可单独使用也可以和list属性同时使用,多个图片资源用英文半角逗号分割 |
选项图片缩放 scale | 数值型 | 当images属性有效时可用此属性设置图片资源缩放比例,范围0 - 1 |
一共有六种属性:编辑框提示文本 prompt、编辑框默认内容 text、 字体大小 size、对齐方式 align、字体颜色 color、键盘类型 kbtype
参数 | 类型 | 说明 |
---|---|---|
编辑框提示文本 prompt | 文本型 | 必填,编辑框中无任何内容时显示的底色文本 |
编辑框默认内容 text | 文本型 | 必填,界面载入时已经存在于编辑框中的文本 |
字体大小 size | 数值型 | 选填,如果不指定该属性,则默认值为 15 |
对齐方式 align | 文本型 | 选填,默认左对齐。可取值为:左对齐 left,右对齐 right,居中 center |
字体颜色 color | 文本型 | 选填,默认黑色。使用RGB十进制数值,以英文半角逗号分割 |
键盘类型 kbtype | 文本型 | 选填,设置获取焦点时弹出的键盘类型,number ascii default |
又称作检查框,一共有五种属性:可选项目标题 list、默认选中项编号 select、控件ID id、在可选项上显示图片 images、选项图片缩放 scale
参数 | 类型 | 说明 |
---|---|---|
可选项目标题 list | 文本型 | 必填,多个可选项目之间用英文半角逗号分割 |
默认选中项编号 select | 文本型 | 必填,允许填写一个或多个,填写多个时以 @ 分割。序号从 0 开始,与可选项目标题中的顺序保持一致 |
控件ID id | 文本型 | 选填,为控件指定ID,可以理解为控件的名称,在返回类型为table时将作为返回table中的key |
在可选项上显示图片 images | 文本型 | 选填,此属性可单独使用也可以和list属性同时使用,多个图片资源用英文半角逗号分割 |
选项图片缩放 scale | 数值型 | 当images属性有效时可用此属性设置图片资源缩放比例,范围0 - 1 |
一共有五种属性:
可选项目标题 list、默认选中项编号 select、两个ComboBox控件建立数据关联时的下级选项 data、两个ComboBox控件建立数据关联时的上级数据源名称 source、两个ComboBox控件建立数据关联时的下级数据源名称 dataSource
参数 | 类型 | 说明 |
---|---|---|
可选项目标题 list | 文本型 | 必填,多个可选项目之间用英文半角逗号分割 |
默认选中项编号 select | 文本型 | 必填,只允许填写一个,序号从 0 开始,与可选项目标题中的顺序保持一致 |
两个ComboBox控件建立数据关联时的下级选项 data | 文本型 | 选填 |
两个ComboBox控件建立数据关联时的上级数据源名称 source | 文本型 | 选填 |
两个ComboBox控件建立数据关联时的下级数据源名称 dataSource | 文本型 | 选填 |
注意事项:
- 默认选中项编号 select 只允许填写一个,序号从 0 开始(此控件需引擎版本 iOS v2.1.3 以上支持)。
- 上一级的必须要有data数据给下级使用,而且list里面逗号分割的个数必须要和data里面#号分割的个数保持一致,上一级的source 和下一级的 dataSource 要保持一致
- 使用了dataSource 就不可以使用list(data、source、dataSource属性需引擎版本 iOS v2.1.8,Android v1.2.4 以上版本支持)
放置一个图片到 UI 上,属性:插入图片的路径 src、
参数 | 类型 | 说明 |
---|---|---|
插入图片的路径 src | 文本型 | 必填,可以是本地路径或者网络路径 |
对齐方式 align | 文本型 | 选填,在 default 模式下设置 image 控件的对齐方式 left center right |
缩放比例 scale | 数值型 | 选填,在 default 模式下设置 image 控件的缩放比例,范围 0 - 1 |
宽度 width | 数值型 | 选填,在 default 模式下设置 image 控件的宽度 |
注意事项:
图片路径的可以是本地路径或者网络路径,例如:\"type\":\"Image\",\"src\":\"http://www.baidu.com/img/bdlogo.png\" 或者\"src\":\"1.png\"
以上六种控件均可重复使用,这个界面的样式 style 为 default,即默认样式,这个样式下的控件将会自动排列,不需要指定其坐标。
另一种界面样式为 custom,当界面样式被指定为这种,则必须指定每个控件的 rect 属性以调整控件的尺寸以及位置,例如:
{
"type": "Edit", "size": 15, "align": "left",
"prompt": "提示文字",
"text": "默认文字",
"color": "255,0,0",
"rect": "0,0,100,40"
}
参数 | 类型 | 说明 |
---|---|---|
尺寸与位置 rect | 文本型 | 必填,该属性适用于全部五种控件,将控件的左上角顶点横坐标、纵坐标,控件宽度、高度分别以英文半角逗号分割。 |
注意事项:
在引擎版本 iOS v2.2.6 以上版本中,自定义模式坐标计算方式由原来的分辨率(pt)改为分辨率(px),开发者使用自定义模式时需要做对应修改,新的方式只需将原自定义模式坐标乘以 Render 屏对应的倍数即可
除了标签 Label,其余四种控件均存在文本型返回值,按照定义时的顺序依次返回给 input_1, input_2, input_3, ...。
单选框返回当前选中项的编号(从 0 开始);
编辑框返回其中的内容;
多选框返回当前选中项的编号(从 0 开始),多个选项以 @ 分割。如:3@5 表示多选框组编号为 3 和 5 的两个选项已被选中。
别忘记,该函数的第一个返回值为整数型 ret,用户单击右下角的“确认”时返回 1,单击左下角的“取消”时返回 0。
通过设置全局属性 rettype
可指定返回值类型适应不同的需求,具体用法参看全局属性介绍部分(此属性需引擎版本 iOS v2.2.6,Android v1.2.7 以上版本支持)。
如果关于返回值调用还是不明白,可以看一下视频教程。
当然你也可以看一下触动精灵官方提供的UI库,非常简洁方便。
local sz = require("sz")
local json = sz.json
w,h = getScreenSize();
MyTable = {
["style"] = "default",
["rettype"] = "table",
["width"] = w,
["height"] = h,
["config"] = "save_01.dat",
["timer"] = 99,
["orient"] = 0,
["pagetype"] = "multi",
["title"] = "触动精灵脚本UI演示",
["cancelname"] = "取消",
["okname"] = "开始",
pages =
{
{
{
["type"] = "Label",
["text"] = "第一页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["id"] = "a01",
["type"] = "RadioGroup",
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
["select"] = "1",
},
{
["type"] = "Label",
["text"] = "请选择",
["width"] = 100,
["nowrap"] = 1,
},
{
["id"] = "year",
["type"] = "Edit",
["width"] = 100,
["prompt"] = "年",
["text"] = "1900",
["kbtype"] = "number",
["nowrap"] = 1,
},
{
["type"] = "Label",
["text"] = "年",
["width"] = 30,
["nowrap"] = 1,
},
{
["id"] = "mon",
["type"] = "ComboBox",
["width"] = 130,
["list"] = "一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月",
["select"] = "1",
["nowrap"] = 1,
},
{
["type"] = "Label",
["text"] = "月",
["width"] = 30,
["nowrap"] = 1,
},
{
["id"] = "day",
["type"] = "ComboBox",
["width"] = 110,
["list"] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31",
["select"] = "1",
["nowrap"] = 1,
},
{
["type"] = "Label",
["text"] = "日",
["width"] = 30,
},
{
["type"] = "Label",
["text"] = "请选择性别:",
["width"] = 170,
["nowrap"] = 1,
},
{
["id"] = "sex",
["type"] = "RadioGroup",
["list"] = "男,女,人妖",
["select"] = "1",
},
},{
{
["type"] = "Label",
["text"] = "第二页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["id"] = "edit01",
["type"] = "Edit",
["prompt"] = "请输入一个字母",
["text"] = "默认值",
["kbtype"] = "ascii",
},
{
["id"] = "edit02",
["type"] = "Edit",
["prompt"] = "请输入一个数字",
["text"] = "默认值",
["kbtype"] = "number",
},
{
["type"] = "Label",
["text"] = "请选择兵种",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["id"] = "arm",
["type"] = "CheckBoxGroup",
["list"] = "兵种1,兵种2,兵种3,兵种4,兵种5,兵种6,兵种7,兵种8,兵种9,兵种10,兵种11,兵种12",
["images"] = "a.png,b.png,c.png,d.png,e.png,f.png,g.png,h.png,i.png,j.png,k.png,l.png",
["select"] = "3@5",
["scale"] = 0.4,
},
},{
{
["type"] = "Label",
["text"] = "第三页设置",
["size"] = 25,
["align"] = "center",
["color"] = "0,0,0",
},
{
["id"] = "a02",
["type"] = "CheckBoxGroup",
["list"] = "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
["select"] = "3@5",
},
{
["id"] = "cb01",
["type"] = "ComboBox",
["list"] = "选项1,选项2,选项3",
["select"] = "1",
["data"] = "子选项1,子选项2,子选项3,子选项4#子选项5,子选项6,子选项7#子选项8,子选项9",
["source"] = "test"
},
{
["id"] = "cb02",
["type"] = "ComboBox",
["select"] = "1",
["dataSource"] = "test"
},
}
}
}
local MyJsonString = json.encode(MyTable);
UIret,values = showUI(MyJsonString)
if UIret == 1 then
nLog("年:"..values.year)
nLog("月:"..values.mon)
nLog("日:"..values.day)
end
- 以上实例需引擎版本iOS v2.2.6,Android v1.2.7 以上版本支持。
- 实例中所使用的图片资源包下载地址:http://pan.baidu.com/s/1jGrVCH4,将图片包中的图片文件解压后放入 /User/Media/TouchSprite/res 目录中,运行实例即可看到效果。
- 实例在 iPhone6S iOS9.0.2 上调试通过,如在其他设备上使用,需自行调整部分参数以适配不同的分辨率。
效果图
名词解析
- JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本 格式,易于人阅读和编写,同时也易于机器解析和生成。
- JSON 中冒号后的值可以是字符串、数字、也可以是另一个数组或对象。
- 转义即取消某些特定的、在编辑语言中被定义为特殊用途的字符。这些字符由于被定义为特殊用途,它们失去了原有的意义,如三种引号 " ' ` 、美元符号 $ 等等。当我们在被引号“括起来”的文本中,想表示出一个引号,就需要转义,如:dialog("\"",5);
注意事项:
- 如果您的系统为 iOS 9 以上版本,并且设备是 iPad,由于一些特殊原因,锁定横屏的时候弹出的UI界面可能无法正常操作,如出现此问题,请将设备改为锁定竖屏。
- 需要注意的是,所有控件的属性值必须按照规则来赋值,错误的赋值类型会导致一些不可预料的结果。
- 为了方便开发者使用,触动精灵提供了封装好的便携 UI 供大家使用,说明文档:https://www.zybuluo.com/miniknife/note/293935
- 在部分安卓设备上需要在系统设置里开启悬浮窗权限方可正常使用 showUI
本类下所有函数都需要引擎版本 iOS v2.3.9 以上版本支持。
在使用此类函数前必须插入以下代码:
local webview = require('webview')
参数 | 类型 | 说明 |
---|---|---|
webview_name | 文本型 | webview 的名字,可以通过不同的名字同时创建多个 webview |
originx | 整数型 | 左上角 x 点坐标缺省为 0 |
originy | 整数型 | 左上角 x 点坐标缺省为 0 |
height | 整数型 | 高度,缺省为全屏 |
width | 整数型 | 宽度,缺省为全屏 |
cornerRadius | 整数型 | 圆角,缺省为 0 |
orient | 整数型 | webview 方向,0-3,和 init 方向一致,缺省为 0 |
root | 文本型 | webview 在文件系统里个根路径,缺省 userPath().."/res" |
index | 文本型 | webview 的入口文件名,缺省 index.html,如果设置了 html, 这个参数就无效了 |
html | 文本型 | 主文件的 html |
返回值 | 类型 | 说明 |
---|---|---|
myweb1 | 表格型 | 创建webview成功返回一个table,失败返回false |
err | 文本型 | 创建webview失败,err返回错误信息 |
函数用例:见完整例子
函数用例:见完整例子
注意事项:
myweb1 为创建 webview 返回的 id
参数 | 类型 | 说明 |
---|---|---|
webview_name | 文本型 | webview 的名字,可以通过不同的名字同时创建多个 webview |
originx | 整数型 | 左上角 x 点坐标缺省为 0 |
originy | 整数型 | 左上角 x 点坐标缺省为 0 |
height | 整数型 | 高度,缺省全屏 |
width | 整数型 | 宽度,缺省全屏 |
cornerRadius | 整数型 | 圆角,缺省为 0 |
orient | 整数型 | webview 方向,0-3,和 init 方向一致,缺省为 0 |
函数用例:见完整例子
注意事项:
myweb1 为创建 webview 返回的对象
函数用例:见完整例子
注意事项:
myweb1 为创建 webview 返回的对象
参数 | 类型 | 说明 |
---|---|---|
event | 文本型 | 事件名称 |
func | 函数型 | 执行的命令 |
函数用例:见完整例子
注意事项:
myweb1 为创建 webview 返回的 id
--示例代码一
local html = [[
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>数据提交简单示例</title>
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!--标准mui.css-->
<!--App自定义的css-->
</head>
<body>
<form id="form1" name="showUI_commit" method="post" action="/set_event">
<br>
<h5>输入框-普通</h5>
<label>输入框:
<input type="text" name="com3" value="测试" placeholder="请输入">
</label>
<br>
<h5>输入框-数字</h5>
<label>输入框:
<input type="number" name="com4" value="1" placeholder="请输入">
</label>
<br>
<h5>输入框-多行</h5>
<label>输入框:
<textarea name="com7" placeholder="请输入" row="5">asd</textarea>
</label>
<br>
<br>
<button id="actions" type="button">提交</button>
<button id="cancel" type="button">取消</button>
</form>
<script type="text/javascript">
function actions(data) {//数据提交post请求
var xhr = new XMLHttpRequest();
xhr.open("POST", "/set_event", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function() {
var XMLHttpReq = xhr;
if (XMLHttpReq.readyState == 4) {
if (XMLHttpReq.status == 200) {
var text = XMLHttpReq.responseText;
console.log(text);
} else {
console.log(XMLHttpReq.status)
}
} else {
console.log(XMLHttpReq.readyState);
}
};
alert('{"name": "showUI_commit","value":' + data + '}')
xhr.send('{"name": "showUI_commit","value":"' + data + '"}');
}
function closed() {//取消post请求
var xhr = new XMLHttpRequest();
xhr.open("POST", "/set_event", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function() {
var XMLHttpReq = xhr;
if (XMLHttpReq.readyState == 4) {
if (XMLHttpReq.status == 200) {
var text = XMLHttpReq.responseText;
console.log(text);
} else {
console.log(XMLHttpReq.status)
}
} else {
console.log(XMLHttpReq.readyState);
}
};
xhr.send('{"name": "showUI_cancel"}');
}
document.getElementById('actions').onclick = function() {//数据提交按钮点击
var com3Val = document.getElementsByName('com3')[0].value; //获取name为com3的值
var com4Val = document.getElementsByName('com4')[0].value; //获取name为com7的值
var com7Val = document.getElementsByName('com7')[0].value; //获取name为com3的值
var data = com3Val + "," + com4Val + "," + com7Val;
actions(data);
}
document.getElementById('cancel').onclick = function() {//取消按钮点击
closed();
}
</script>
</body>
</html>
]]
local thread = require('thread')
local event = require('event')
--创建webview
local showui_view,err = require('webview').new("myshowui",
{html=html})
assert(showui_view,err)
event.register("showUI_commit",function(value)
local sz = require('sz')
local json = sz.json
toast(json.encode(value),5)
showui_view.close()
end)
event.register("showUI_cancel",function(value)
showui_view.close()
end)
showui_view.show()
thread.waitAllThreadExit()
--示例代码二
local html = [[
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello 触动精灵 ShowUI</title>
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!--标准mui.css-->
<link rel="stylesheet" href="css/tsShowUI.css">
<!--App自定义的css-->
</head>
<body>
<header class="mui-bar mui-bar-nav">
<button id="ts-cancle" class="mui-action-back mui-btn mui-btn-blue mui-btn-link mui-btn-nav mui-pull-left"><span class="mui-icon mui-icon-left-nav"></span><span class=" mui-tscancel">返回</span></button>
<h1 class="mui-title mui-tstitle"></h1>
</header>
<footer class="mui-bar mui-bar-footer mui-bar-tsfooter">
<button id="ts-post-btn" class="mui-ts-footerbth btn mui-btn-block mui-btn-blue mui-tsaction" data-loading-text="执行中" type="button">开始</button>
</footer>
<div class="mui-content">
<form class="mui-tsform">
<div class="mui-card" id="renderbox">
</div>
</form>
</div>
<script src="js/tsShowUI.js"></script>
<script>
(function($, doc) {
var uiVersion=$.getVersion();//获取ui版本
//json兼容原showui 格式
var showui_json = {
"title": "触动精灵脚本配置", //给页面添加标题(默认标题无)
"cancelname": "取消", //给页面取消按钮添加文字(默认文字无)
"config": "save_01",
"okname": "开始", //给页面开始按钮添加文字(默认“开始”)
"style": "default",
"timer": 99,
"orient": 0,
"pagetype": "multi",
"view": [{
"type": "Label",
"text": "标题1",
"size": 18,
"align": "center",
"color": "0,168,233"
}, {
"type": "Image",
"src": "http://www.touchsprite.com/wp-content/uploads/2016/10/banner2_790x230-790x0.png"
}, {
"type": "Label",
"text": "switches控件",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"type": "switches",
"list": "开关1,开关2,开关3",
"select": "0@2"
}, {
"type": "Label",
"text": "RadioGroup控件",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi4",
"type": "RadioGroup",
"list": "选项1,选项2,选项3",
"select": "1"
}, {
"type": "Label",
"text": "Edit控件(普通)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi5",
"type": "Edit",
"prompt": "请输入一个字母",
"text": "默认值",
"kbtype": "ascii"
}, {
"type": "Label",
"text": "Edit控件(多行)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi6",
"type": "Edit",
"prompt": "请输入一个字母",
"text": "默认值",
"row": "5",
"kbtype": "ascii"
}, {
"type": "Label",
"text": "Edit控件(滑块)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"type": "Edit",
"prompt": "请输入一个数字",
"text": "2",
"kbtype": "range",
"max": "100",
"min": "0",
}, {
"type": "Label",
"text": "Edit控件(数字)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi7",
"type": "Edit",
"prompt": "请输入一个数字",
"text": "123456",
"kbtype": "number"
}, {
"type": "Label",
"text": "Edit控件(密码)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi8",
"type": "Edit",
"prompt": "请输入密码",
"text": "hhkjkjh",
"kbtype": "password"
}, {
"type": "Label",
"text": "CheckBoxGroup控件",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi9",
"type": "CheckBoxGroup",
"list": "选项1,选项2,选项3,选项4",
"select": "0@3",
}, {
"type": "Label",
"text": "ComboBox控件(二级)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi10",
"type": "ComboBox",
"list": "选项1,选项2,选项3",
"select": "2",
"data": "子选项1,子选项2,子选项3,子选项4#子选项5,子选项6,子选项7#子选项8,子选项9",
"source": "test"
}, {
"type": "Label",
"text": "ComboBox控件(一级)",
"size": 16,
"align": "left",
"color": "0,168,233"
}, {
"id": "ceshi11",
"type": "ComboBox",
"list": "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
"select": "1"
}]
};
$.renderUI(showui_json);
})(mui, document)
</script>
</body>
</html>
]]
local thread = require('thread')
local event = require('event')
local sz = require('sz')
local json = sz.json
--创建webview
local showui_view,err = require('webview').new("myshowui",
{html=html})
assert(showui_view,err)
event.register("showUI_commit",function(value)
toast(json.encode(value),10)
showui_view.close()
end)
event.register("showUI_cancel",function(value)
showui_view.close()
end)
showui_view.show()
thread.waitAllThreadExit()
在安卓某些 HTML 页面,使用 inputText 函数输入无效,可尝试使用模拟物理按键。约定的按键编码具体见附录。
实例:
os.execute("input keyevent 按键编码")
--按下home键
os.execute("input keyevent 3")
--打电话给10086
os.execute("input keyevent 5") --按拨号键
os.execute("input text \"10086\"") --输入10086
os.execute("input keyevent 5") --按拨号键打通
友友们是不是感觉触动精灵提供的插件调用起来不方便,触动内置的功能十分有限?你需要什么?
文件系统操作(新建、删除、建立符号链接)……
文件格式解析(zip, rar, plist, deb)……
网络操作(http, https, ftp, sftp, ftps, udp, smtp, imap)……
图像处理(png, bmp, jpg, tiff)……
问题:有没有更加好用的 Lua 原生扩展方式呢?
答案:有!而且 Lua 扩展有很多!
Lua 的扩展(add-on)基本上来自于这两个网站:
http://luaforge.net/projects
https://rocks.moonscript.org
熟悉跨平台编译的开发者当然可以试试自己编译这当中的插件给 iOS 使用。
如果有 C 语言、Objective-C、C++ 开发能力的,当然也可以自己编写 Lua 原生扩展,还能使用 iOS 的 SDK。
用 Objective-C 给 Lua 编写扩展并在 iOS 平台上运行
关于如何编写 Lua 扩展,参见 Lua 官方文档,这里并不作介绍,以下实例及说明由 i82 提供。
mt.m:
#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIDevice.h>
/* 库 open 函数的前置声明 */
int luaopen_mt(lua_State *L);
/* Function mt_get_device_name
* @return string device name
*/
static int mt_get_device_name(lua_State *L)
{
NSString *name = [[UIDevice currentDevice] name];
const char * name_str = [name UTF8String];
lua_pushstring(L, name_str);
return 1;
}
//注册函数库
static const luaL_Reg mt_lib[] = {
{"device_name", mt_get_device_name}, //获取设备名称
{NULL, NULL}
};
int luaopen_mt(lua_State *L)
{
luaL_newlib(L, mt_lib);
return 1;
}
单个源文件的编译与连接命令(将 gcc 换成 g++ 可使用 Objective-C++ 语法):
xcrun -sdk iphoneos gcc -arch armv7 -arch armv7s -arch arm64 -miphoneos-version-min=4.3 -O3 -std=c99 -I/opt/theos/include/ -c -o mt.o mt.m
xcrun -sdk iphoneos gcc -arch armv7 -arch armv7s -arch arm64 -miphoneos-version-min=4.3 -O3 -framework Foundation -framework UIKit -bundle -undefined dynamic_lookup -o mt.so mt.o
得到的 mt.so 即可在 Lua 中引用了:
local mt = require "mt"
print(mt.device_name())
为了进一步降低脚本开发者门槛,触动精灵单独开发了 TSLib 函数扩展库,提供了一系列实用函数供开发者使用。
函数库开发手册:https://www.zybuluo.com/miniknife/note/293935
函数:getAppName 获取应用名称
函数:getUserApp 获取用户安装非越狱应用
函数:getRender 获取屏幕的render值
函数:isDay 判断日期
函数:checkTable 检查UItable
函数:getMode 获取 UI 模式
函数:neosUI 显示UI
"本地光学字符识别" 简称本地 OCR,由于特征库、性能的限制,识别速度慢、识别率也比较差,触动精灵提供了 Lua 云打码扩展库来解决这一问题。
需要注意的是,帮你玩平台不能使用此函数库,小精灵平台要使用打码库请勾选网络插类型。
使用说明:https://www.zybuluo.com/miniknife/note/293935#ocr云打码扩展库
注意事项:
- 触动苹果安卓,扩展库 v1.1.5以上版本支持,区别于官方打码
- 触动小精灵使用此打码库需要勾选
网络插件
类型- 如果函数返回false都为网络错误超时
- 扩展库支持如下打码平台:
- http://www.haoi23.net/ --好爱
- http://www.dama2.com/ --打码兔
- http://www.chaorendama.com/ --QQ 超人
"本地光学字符识别" 简称本地 OCR 由于特征库、性能的限制,识别速度慢、识别率也比较
差。触动精灵提供云打码扩展库来解决这一问题。该扩展库支持如下打码平台:
1. http://www.haoi23.net/ --好爱
2. http://www.dama2.com/ --打码兔
3. http://www.uudama.com/ --UU 云
4. http://www.hyocr.com/ --火眼
- 下载扩展库,将 cloudOcr.so 插件放入脚本 /lua 目录或插件/plugin 目录,在脚本开头插入 local ocr = require "cloudOcr" 即可。
- 安装触动精灵 2.0.9 以上版本,在 更多- 插件中在线安装,在脚本开头插入 local ocr = require "cloudOcr" 即可。
- cloudOcr.so下载链接:http://pan.baidu.com/s/1nvFMxCl
参数 | 类型 | 说明 |
---|---|---|
platform | 文本型 | 平台类型,打码兔 - dama2;优优云 - uuwise;火眼 - hyocr;好爱 - haoi23 |
x1,y1 | 整数型 | 识别区域左上角顶点坐标 |
x2,y2 | 整数型 | 识别区域右下角顶点坐标 |
type | 文本型 | 打码类型,可在对应平台官网查询 |
username | 文本型 | 打码平台用户名,需用户去相应平台自行注册 |
password | 文本型 | 打码平台密码,需用户去相应平台自行注册 |
length | 整数型 | 打码长度(可选参数),默认为 0 |
timeout | 整数型 | 超时时间(可选参数),默认为 10 秒 |
scale | 整数型 | 缩放比例(可选参数),默认为 100,即不进行缩放 |
返回值 | 类型 | 说明 |
---|---|---|
ret.success | 布尔型 | true 打码成功,false 失败 |
ret.text | 文本型 | 返回的识别结果,在 success == true 时存在 |
ret.message | 文本型 | 消息,在 success == fasle 时,返回错误原因 |
ret.id | 表格型 | 打码标识,在 success == true 时存在,用于打码自动纠错 |
脚本实例:
local ocr = require "cloudOcr";
local op = {
--必填参数
["platform"]="dama2", --平台类型,具体参数参照参数表
["x1"]=1848, --需要识别区域左上角坐标
["y1"]=473,
["x2"]=2029, --需要识别区域右下角坐标
["y2"]=561,
["type"]="52", --打码类型,可在对应平台官网查询
["username"]="user", --打码平台账号
["password"]="password", --打码平台密码
--选填参数
["length"]=4, --打码长度
["timeout"]=30, --超时时间
["scale"]=50, --缩放比例,范围10 - 200,在某些待识别区域过大的时候可设置此参数
};
local ret = ocr.cloudOcrText(op);
if ret.success then
dialog(ret.text,0)
else
dialog(ret.message,0)
end
--自动纠错
local ocr = require "cloudOcr"; --载入扩展库
local ret = ocr.cloudOcrText(op); --进行远程识别
if ret.success then
ret_1 = ocr.cloudOcrReportError(ret.id); --自动纠错,ret.id从ocr.cloudOcrText返回值中获取
end
local ocr = require "cloudOcr";
local ver = ocr.version(); --获取扩展库版本号
注意事项:
- 最新云打码可在触动精灵 iOS v2.0 以上版本插件管理中下载安装。
- 打码函数传入的参数为 table 类型,使用时请参照参数表中详细说明。
- 如您使用火眼答题平台,用户名参数可以为空,密码串需要用户注册登陆后可以在火眼平台的后台查看到。
- 如您使用好爱答题平台,用户名参数可任意填写,密码参数格式: username|密码串,密码串需用户注册登录后可在好爱平台后台查看到。
- 帮你玩、小精灵使用此插件需自行将插件打包到脚本压缩包内或导入手机对应目录。
参数 | 类型 | 说明 |
---|---|---|
参数 1 | 文本型 | 发送者邮件地址 |
参数 2 | 文本型 | 接收者邮件地址 |
参数 3 | 文本型 | 邮件主题 |
参数 4 | 文本型 | 邮件正文 |
参数 5 | 文本型 | SMTP 服务器 |
参数 6 | 文本型 | SMTP 鉴定用户名 |
参数 7 | 文本型 | SMTP 鉴定密码 |
脚本实例:
local mail = require "mail"
a = mail.send("i.82@82flex.com", "357722984@qq.com", "Hello", "This is a test mail.", "smtp.mxhichina.com", "i.82@82flex.com", "***")
if a == true then --发送成功
dialog("Succeed!", 0)
else
dialog(a, 0)
end
注意事项:
- 扩展库下载地址:http://pan.baidu.com/s/1hqjCtVm 下载后将 mail.so 放入 /var/mobile/Media/TouchSprite/plugin 即可在脚本中引用。
Lua 配合 os.execute 命令,可以使用触动精灵对 iOS 设备进行注销、关机、重启、清空缓存、解压、移动、复制、删除文件、创建文件夹等系统操作
帮你玩平台禁用此函数。
--注销
function respring()--帮你玩平台禁用此函数
os.execute("killall -9 SpringBoard");
end
--关机
function poweroff()--帮你玩平台禁用此函数
os.execute("halt");
end
--重启
function reboot()--帮你玩平台禁用此函数
os.execute("reboot");
end
--清空缓存
function clearCache()--帮你玩平台禁用此函数
os.execute("su mobile -c uicache");
end
--删除文件
function delFile(path)--帮你玩平台禁用此函数
os.execute("rm -rf "..path);
end
参数说明
参数 | 说明 |
---|---|
path | 要删除文件的路径,支持*通配符 |
脚本实例:
如要删除1.lua的文件,则输入:
delFile("/var/mobile/Media/TouchSprite/lua/1.lua");
--解压zip文件
function unzip(path,to)--帮你玩平台禁用此函数
os.execute("unzip "..path.." -d "..to);
end
参数说明
参数 | 说明 |
---|---|
path | 为待解压文件的路径 |
to | 要解压到的文件夹路径,默认不覆盖 |
脚本实例:
如要解压名为 1.zip 的文件,则输入:
unzip("/var/mobile/Media/TouchSprite/lua/1.zip","/var/mobile/Media/TouchSprite/lua/");
--移动文件
function movefile(path,to)--帮你玩平台禁用此函数
os.execute("mv "..path.." "..to);
end
参数说明
参数 | 说明 |
---|---|
path | 待移动文件的路径,支持*通配符 |
to | 要移动到的文件路径,注意先判断是否有重名文件或文件夹 |
脚本实例:
如要移动1.txt到lua/1.lua,则输入:
movefile("/var/mobile/Media/TouchSprite/lua/1.txt","/var/mobile/Media/TouchSprite/lua/1.lua");
--复制文件
function copyfile(path,to)
os.execute("cp -rf "..path.." "..to);
end
参数说明
参数 | 说明 |
---|---|
path | 待复制文件的路径,支持*通配符 |
to | 要复制到的文件路径,注意先判断是否有重名文件或文件夹。 |
脚本实例:
如要复制res/1.txt到lua/1.txt,则输入:
copyfile("/var/mobile/Media/TouchSprite/res/1.txt","/var/mobile/Media/TouchSprite/lua/1.txt");
--创建文件夹
function newfolder(path)--帮你玩平台禁用此函数
os.execute("mkdir "..path);
end
参数说明
参数 | 说明 |
---|---|
path | 要创建文件夹的路径 |
脚本实例:
如要创建test文件夹,则输入:
newfolder("/var/mobile/Media/TouchSprite/lua/test");
--将指定文件中的内容按行读取
function readFile(path)
local file = io.open(path,"r");
if file then
local _list = {};
for l in file:lines() do
table.insert(_list,l)
end
file:close();
return _list
end
end
list = readFile("/User/Media/TouchSprite/lua/1.txt");
参数说明
参数 | 说明 | 返回值 |
---|---|---|
path | 要读取文件的路径 | table |
--遍历文件
function getList(path)
local a = io.popen("ls "..path);
local f = {};
for l in a:lines() do
table.insert(f,l)
end
return f
end
参数说明
参数 | 说明 | 返回值 |
---|---|---|
path | 要列举文件的文件夹的路径 | table |
脚本实例:
如要列举触动精灵lua文件夹下所有的脚本文件,则输入:
list = getList("/User/Media/TouchSprite/lua/");
--查找文件
function findFile(path)
local a = io.popen("find "..path.." -prune");
local f = {};
for l in a:lines() do
table.insert(f,l)
end
return f
end
参数说明
参数 | 说明 | 返回值 |
---|---|---|
path | 要查找文件的路径,支持*通配符 | table |
脚本实例:
如要查找后缀为.lua的文件,则输入:
file = findFile("/User/Media/TouchSprite/lua/*.lua");
--检测指定文件是否存在
function file_exists(file_name)
local f = io.open(file_name, "r")
return f ~= nil and f:close()
end
参数说明
参数 | 说明 | 返回值 |
---|---|---|
path | 要查找文件的路径 | true/false |
脚本实例:
if file_exists("/User/Media/TouchSprite/lua/1.lua") then
dialog("文件存在",0)
else
dialog("文件不存在",0)
end
LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。
注意事项:
帮你玩开发者平台禁用此函数库,打码请使用函数扩展库代替,详见函数扩展库开发手册
在触动精灵iOS v2.1.9 及以上版本中包含的苏泽扩展库中已经集成了luasocket,无需额外下载安装。
脚本示例:
local sz = require("sz")
local http = require("szocket.http")
local res, code = http.request("http://www.baidu.com");
if code == 200 then
dialog(res,0);
end
--也可以这样
local response_body = {}
local res, code = http.request({
url = "http://www.baidu.com",
sink = ltn12.sink.table(response_body)
})
--获取外网ip地址
local sz = require("sz")
local http = require("szocket.http")
local res, code = http.request("http://www.ip.cn/");--如果此网址无反应,请尝试替换为 http://1212.ip138.com/ic.asp 或其他网址
if code == 200 then
local i,j = string.find(res, "%d+%.%d+%.%d+%.%d+")
local ipaddr =string.sub(res,i,j)
dialog(ipaddr,0)
end
注意事项:
- 返回的2个参数中,res 是 http body 的内容,也就是请求网页的内容,code 是 http 状态码, 返回200的话就表示正常返回。
- 如果传入的是 table 的话,就需要用一个容器来接收 http body 的内容。
脚本示例:
local sz = require("sz")--此代码仅为举例说明,请勿直接复制使用。
local http = require("szocket.http")
local response_body = {}
local post_data = 'asd';
res, code = http.request{
url = "http://127.0.0.1/post.php",
method = "POST",
headers =
{
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = #post_data,
},
source = ltn12.source.string('data=' .. post_data),
sink = ltn12.sink.table(response_body)
}
注意事项:
- 这里注意记得 method 传入
POST
, 因为默认是 GET。- headers 参数,由一个 table 组成,key 为 header,value 为 header 内容。
- source 参数,这里是填入 POST 的参数,多个数据的情况用
&
隔开,例如 "data1=a&data2=b"。- 此代码仅为举例说明,请勿直接复制使用。
脚本示例:
--必须加上 http:// 否则不处理
local sz = require("sz")
local http = require("szocket.http")
http.PROXY = "http://127.0.0.1:8888" --代理服务器地址
local result = http.request("http://www.baidu.com")
dialog(result,0)
脚本示例:
local sz = require("sz")
local http = require("szocket.http")
local host = "www.baidu.com"
local file = "/"
local sock = assert(socket.connect(host, 80)) --创建一个 TCP 连接,连接到 HTTP 连接的标准 80 端口上
sock:send("GET " .. file .. " HTTP/1.0\r\n\r\n")
repeat
local chunk, status, partial = sock:receive(1024) --以 1K 的字节块接收数据
until status ~= "closed"
sock:close() -- 关闭 TCP 连接
脚本示例:
local sz = require("sz")
local smtp = require("szocket.smtp")
from = "<youmail@126.com>" -- 发件人
--发送列表
rcpt = {
"<youmail@126.com>",
"<youmail@qq.com>",
"<youmail@gmail.com>",
}
mesgt = {
headers = {
to = "youmail@gmail.com", -- 收件人
cc = '<youmail@gmail.com>', -- 抄送
subject = "This is Mail Title"
},
body = "这里放邮件内容"
}
r, e = smtp.send{
server = "smtp.126.com", --smtp服务器地址
user = "youmail@126.com",--smtp验证用户名
password = "******", --smtp验证密码
from = from,
rcpt = rcpt,
source = smtp.message(mesgt)
}
if not r then
dialog(e,0);
else
dialog("发送成功!",0);
end
脚本示例:
local sz = require("sz")
local socket = require "szocket.core"
server_ip = {
"132.163.4.101",
"132.163.4.102",
"132.163.4.103",
"128.138.140.44",
"192.43.244.18",
"131.107.1.10",
"66.243.43.21",
"216.200.93.8",
"208.184.49.9",
"207.126.98.204",
"207.200.81.113",
"205.188.185.33"
}
function nstol(str)
assert(str and #str == 4)
local t = {str:byte(1,-1)}
local n = 0
for k = 1, #t do
n= n*256 + t[k]
end
return n
end
function gettime(ip)
local tcp = socket.tcp()
tcp:settimeout(10)
tcp:connect(ip, 37)
success, time = pcall(nstol, tcp:receive(4))
tcp:close()
return success and time or nil
end
function nettime()
for _, ip in pairs(server_ip) do
time = gettime(ip)
if time then
return time
end
end
end
dialog(nettime(),0)
脚本示例:
local sz = require("sz")
local socket = require ("szocket")
function sleep(sec)
socket.select(nil,nil,sec);
end
local t0 = socket.gettime()
sleep(0.4);
local t1 = socket.gettime()
dialog(t1 - t0,0)
脚本示例:
1. 设置随机种子
--设置随机种子
local sz = require("sz")
local socket = require("szocket") -- 需要用到luasocket库
local function get_seed()
local t = string.format("%f", socket.gettime())
local st = string.sub(t, string.find(t, "%.") + 1, -1)
return tonumber(string.reverse(st))
end
math.randomseed(get_seed())
for var = 1,5 do
nLog(math.random())
end
--随机字符串
function randomStr(str, num)
local ret =''
for i = 1, num do
local rchr = math.random(1, string.len(str))
ret = ret .. string.sub(str, rchr, rchr)
end
return ret
end
--用法
for var = 1,5 do
s = randomStr("abcdefghijklmnopqrstuvwxyz", 6) --生成6位随机字母
nLog(s)
end
--随机大小写
function rndLetter(num)
local ret = ""
pcall(function()
for var = 1,num do
if math.random()>0.5 then
ret = ret..string.char(math.random(65,90))
else
ret = ret..string.char(math.random(97,122))
end
end
end)
return ret
end
--用法
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6))) --设置随机种子
for var = 1,5 do
nLog(rndLetter(10)) --生成一个10位随机大小写字母的字符串
end
函数库开发手册地址:https://www.zybuluo.com/miniknife/note/671299
函数扩展库下载
说明:此扩展库通用于 iOS/Android 平台。
JSON 模块
FTP 模块
设备信息模块
字符串处理模块
HTTP 模块
HTTPS 模块
Socket 模块
PLIST 文件操作
SMTP 发送邮件
获取设备网络类型
Ping 测试网络连接情况
获取毫秒级时间戳
下载文件
二维码图片生成
简单数据存储
数据库操作
文件管理
为了进一步降低脚本开发者门槛,触动精灵iOS 2.x 以上版本集成了苏泽的扩展库,提供了一系列实用函数供开发者使用,在这里再次感谢 苏泽
为广大开发者及触动做出的杰出贡献。
使用方法:
请在脚本开头插入 local sz = require("sz")
即可调用扩展库中所有函数。
函数名称:sz.json.encode、sz.json.decode
函数功能:json串编码、解码
脚本实例:
local sz = require("sz")--使用苏泽库前必须插入这一句
local json = sz.json--使用JSON 模块前必须插入这一句
local tb = {
["我"] = "苏泽",
["爱"] = "娜娜",
meme = {
isArray = true,
1,0,0,4,6,9,5,1,0,0,
},
nullvalue = null,
}
local jsonstring = json.encode(tb);
dialog(jsonstring, 0);
local tmp = json.decode(jsonstring);
dialog(tmp.meme[5], 0);
dialog(tostring(tmp.nullvalue), 0);
--unicode 转 utf8
local sz = require "sz"
local tmp = sz.json.totable([[{"toUTF8":"\u6211\u7231\u5a1c\u5a1c"}]])
dialog(tmp["toUTF8"],0)
注意事项:
在 JSON 格式的 ShowUI 时会用到JSON 模块
函数名称:ftp.download、ftp.upload、ftp.cmd
函数功能:FTP上传、FTP下载、执行FTP命令
函数方法:
ftp = sz.ftp
ftp.download(文本型 ftppath, 文本型 path)
ftp.upload(文本型 path, 文本型 ftppath)
ftp.cmd(文本型 ftppath, 文本型 cmd)
参数 | 类型 | 说明 |
---|---|---|
ftppath | 文本型 | 格式为 ftp://ftp用户名:ftp密码@ftp服务器ip地址/文件名,文件名不可使用中文字符 |
path | 文本型 | 需填写完整路径 |
cmd | 文本型 | FTP 操作命令:DELE 删除,LIST 列出 |
脚本实例:
1. FTP 下载一个文件到本地
local sz = require("sz")--使用苏泽库前一定要在开头插入这一句
local ftp = sz.ftp--使用FTP 模块前一定要插入这一句
_, err = ftp.download("ftp://admin:ts123456@192.168.1.0/config.dat", "/var/mobile/Media/TouchSprite/config/config.dat")--文件名不可使用中文字符
if err then
dialog(err, 0)
else
dialog("文件已下载成功", 0)
end
local sz = require("sz")--使用苏泽库前一定要在开头插入这一句
local ftp = sz.ftp--使用FTP 模块前一定要插入这一句
_, err = ftp.upload("/var/mobile/Media/TouchSprite/lua/config.dat", "ftp://admin:ts123456@192.168.1.0/Games/")--文件名不可使用中文字符
if err then
dialog(err, 0)
else
dialog("文件已上传成功", 0)
end
local sz = require("sz")--使用苏泽库前一定要在开头插入这一句
local ftp = sz.ftp--使用FTP 模块前一定要插入这一句
_, err = ftp.cmd("ftp://admin:ts123456@192.168.1.0/Games/", "DELE config.dat")--文件名不可使用中文字符
if err then
dialog(err, 0)
else
dialog("文件删除成功", 0)
end
local sz = require("sz")--使用苏泽库前一定要在开头插入这一句
local ftp = sz.ftp--使用FTP 模块前一定要插入这一句
msg, err = ftp.cmd("ftp://admin:ts123456@192.168.1.0/Games/", "LIST")
if err then
dialog(err, 0)
else
dialog("文件列表\n"..msg, 0)
end
注意事项:
- 使用本模块时填写的文件路径中,文件名不能使用中文字符
- 文件路径必须填写完整路径
函数名称:sz.system.udid
函数功能:获取设备
函数方法
udid = sz.system.udid()
返回值:文本型 udid
返回值 | 类型 | 说明 |
---|---|---|
udid | 文本型 | 设备 UDID |
脚本实例:
local sz = require("sz")
udid = sz.system.udid() --获取设备的 UDID
dialog(udid, 0)
函数名称:sz.system.serialnumber
函数功能:获取设备序列号
函数方法
serialnumber = sz.system.serialnumber()
返回值:文本型 serialnumber
返回值 | 类型 | 说明 |
---|---|---|
serialnumber | 文本型 | 设备序列号 |
脚本实例:
local sz = require("sz")
serialnumber = sz.system.serialnumber()--获取设备的序列号
dialog(serialnumber, 0)
函数名称:sz.system.wifimac
函数功能:获取设备 WiFi MAC地址
函数方法
wifimac = sz.system.wifimac()
返回值:文本型 wifimac
返回值 | 类型 | 说明 |
---|---|---|
wifimac | 文本型 | 设备 WiFi MAC 地址 |
脚本实例:
local sz = require("sz")
wifimac = sz.system.wifimac() --获取设备的 WiFi MAC 地址
dialog(wifimac, 0)
函数名称:sz.system.btmac
函数功能:获取设备蓝牙 MAC 地址
函数方法
btmac = sz.system.btmac()
返回值:文本型 btmac
返回值 | 类型 | 说明 |
---|---|---|
btmac | 文本型 | 蓝牙 MAC 地址 |
脚本实例:
local sz = require("sz")
btmac = sz.system.btmac() --获取设备的蓝牙 MAC 地址
dialog(btmac, 0)
函数名称:sz.system.osversion
函数功能:获取设备系统版本号
函数方法
osversion = sz.system.osversion()
返回值:文本型 osversion
返回值 | 类型 | 说明 |
---|---|---|
osversion | 文本型 | 设备系统版本号 |
脚本实例:
local sz = require("sz")
osversion = sz.system.osversion() --获取设备的系统版本号
dialog(osversion, 0)
函数名称:sz.system.mgcopyanswer("ProductType")
函数功能:获取设备详细型号
函数方法
producttype = sz.system.mgcopyanswer("ProductType")
返回值:文本型 producttype
返回值 | 类型 | 说明 |
---|---|---|
producttype | 文本型 | 设备详细型号 |
脚本实例:
local sz = require("sz")
producttype = sz.system.mgcopyanswer("ProductType")--获取设备详细型号
dialog(producttype,0)
注意事项:
详细型号指的是 iPhone5,3
函数名称:sz.system.mgcopyanswer("UserAssignedDeviceName")
函数功能:获取设备名称
函数方法
devicename = sz.system.mgcopyanswer("UserAssignedDeviceName")
返回值:文本型 devicename
返回值 | 类型 | 说明 |
---|---|---|
devicename | 文本型 | 设备名称 |
脚本实例:
local sz = require("sz")
devicename = sz.system.mgcopyanswer("UserAssignedDeviceName")--获取设备名称
dialog(devicename,0)
注意事项:
获取的设备名称是
设置-通用-关于本机-名称
处用户自己设置的名称。
函数名称:sz.system.mgcopyanswer("InternationalMobileEquipmentIdentity")
函数功能:获取设备 IMEI
函数方法
imei = sz.system.mgcopyanswer("InternationalMobileEquipmentIdentity")
返回值:文本型 imei
返回值 | 类型 | 说明 |
---|---|---|
imei | 文本型 | 设备 IMEI |
脚本实例:
local sz = require("sz")
imei = sz.system.mgcopyanswer("InternationalMobileEquipmentIdentity") --获取设备 IMEI
dialog(imei,0)
函数名称:sz.system.localwifiaddr
函数功能:获取本地网络地址
脚本实例:
local sz = require("sz")
local ret = ""
for i,v in ipairs(sz.system.localwifiaddr()) do --获取本地网络地址
ret = ret..(v[1]).."="..(v[2]).."\n"
end
dialog(ret,0)
注意事项:
iOS 引擎版本 v2.1.9 以上版本中采用新版苏泽扩展库,sz.system.localwifiaddr() 将返回一个 TABLE,TABLE 中包含本地内部环回地址、蜂窝地址、本地 WiFi 地址。
函数名称:tohex、fromhex
函数功能:转码,字符串十六进制编码转换
脚本实例:
local sz = require("sz")
local str = "触动精灵"
dialog('"'..str..'" 的 16 进制编码为: <'..str:tohex()..'>', 0) --“触动精灵”的 16 进制编码
dialog('<'..str:tohex()..'> 转换成明文为: "'..str:tohex():fromhex()..'"', 0)--将上一行的 16 进制编码转换为明文字符
函数名称:md5
函数功能:字符串 MD5 计算
md5;
脚本实例:
local sz = require("sz")
local str = "触动精灵"
local binstr = "\0\1\2\3\4\5"
dialog('"'..str..'" 的 MD5 值是: '..str:md5(), 0)--计算"触动精灵"的 MD5 值
dialog('<'..binstr:tohex()..'> 的 MD5 值是: '..binstr:md5(), 0)--计算“000102030405”的 MD5 值
函数名称:sha1
函数功能:字符串 SHA1 计算
sha1;
脚本实例:
local sz = require("sz")
local str = "触动精灵"
local binstr = "\0\1\2\3\4\5"
dialog('"'..str..'" 的 SHA1 值是: '..str:sha1(), 0)--计算"触动精灵"的 SHA1 值
dialog('<'..binstr:tohex()..'> 的 SHA1 值是: '..binstr:sha1(), 0) --计算“000102030405”的 SHA1 值
函数名称:aes128_encrypt、aes128_decrypt、base64_encode、base64_decode
函数功能:字符串 AES128、BASE64 编解码
脚本实例:
local sz = require("sz")
local msg = "\5\4\3\2\1\0"
local key = "触动精灵"
local emsg = msg:aes128_encrypt(key)
local emsgb64 = emsg:base64_encode()
dialog('二进制数据<'..msg:tohex()..'> \n 使用 AES128 算法 密钥 "'..key..'" 加密 值是: <'..emsg:tohex()..'> \n base64 串为 "'..emsgb64..'"', 0)
local tmp = emsgb64:base64_decode()
msg = tmp:aes128_decrypt(key)
dialog('"'..emsgb64..'" base64 解码后的数据为 <'..tmp:tohex()..'> \n使用 AES128 算法 密钥 "'..key..'" 解密 值是: <'..msg:tohex()..'>', 0)
函数名称:split、rtrim、ltrim、trim、atrim
函数功能:字符串分割、过滤
脚本实例:
字符串分割及空白字符过滤
local sz = require("sz")
str = " 哈哈,he he,1,3,6 "
new = str:split(",") --将字符串str按照 `,` 分割并返回一个TABLE
dialog(new[2], 0)
dialog(str:rtrim(), 0) -- 结果 " 哈哈,he he,1,3,6" ,删除字符串尾部的空白字符
dialog(str:ltrim(), 0) -- 结果 "哈哈,he he,1,3,6 " ,删除字符串首部的空白字符
dialog(str:trim(), 0) -- 结果 "哈哈,he he,1,3,6" ,删除字符串首尾的空白字符
dialog(str:atrim(), 0) -- 结果 "哈哈,hehe,1,3,6" ,删除字符串所有的空白字符
名词解析:
空白字符包括:空格、制表符
\t
、换行符\n
、\r
。
函数名称:fromgbk
函数功能:转码,GBK 转 UTF8
脚本实例:
将字符串从 GBK 编码转换到 UTF8 编码(需iOS 引擎版本 v2.2.6 以上版本)
require "sz"
f = io.open("/var/mobile/Media/TouchSprite/res/a.txt", "r")
s = f:read("*a")
f:close()
dialog(s:fromgbk())
函数名称:iconv
函数功能:字符集转换
脚本实例:
--此功能需iOS 引擎版本 v2.2.7 以内置版本带的苏泽库支持方可使用
local sz = require("sz")
local iconv = sz.iconv
local cd = iconv.new("utf8", "gbk") --新建一个gbk到utf8编码的转换器
local f = io.open("/var/mobile/Media/TouchSprite/res/1.txt", "rb")
local s = f:read("*a")
f:close()
dialog(cd:iconv(s))
参数 | 类型 | 说明 |
---|---|---|
url | 文本型 | 请求URL (必须填写) |
time_out | 整数型 | 超时时间(秒) |
headers_send | 文本型 | 请求头部 json |
post_escaped | 文本型 | 请求内容 |
返回值 | 类型 | 说明 |
---|---|---|
status_resp | 整数型 | HTTP 状态码 |
headers_resp | 文本型 | 响应头部 json |
body_resp | 文本型 | 响应内容 |
脚本实例:
--采用 cjson 构造请求头部 json
local sz = require("sz")
local cjson = sz.json
local http = sz.i82.http
headers = {}
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36'
headers['Referer'] = 'http://www.82flex.com'
headers_send = cjson.encode(headers)
dialog(headers_send,0)
status_resp, headers_resp, body_resp = http.get("http://82flex.com", 5, headers_send)
if status_resp ~= nil then
dialog(status_resp,0)
dialog(headers_resp,0)
if status_resp == 200 then
dialog(string.len(body_resp),0)
end
end
--采用 cjson 构造请求头部 json
local sz = require("sz")
local cjson = sz.json
local http = sz.i82.http
headers = {}
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36'
headers['Referer'] = 'http://www.touchsprite.net/site/login'
headers_send = cjson.encode(headers)
dialog(headers_send,0)
--采用 cjson 构造请求内容,并进行 escape
post = {}
post['username'] = "i_82"
post['password'] = '12345678'
post['text'] = '触动精灵'
post_send = cjson.encode(post)
dialog(post_send,0)
post_escaped = http.build_request(post_send)
dialog(post_escaped,0)
status_resp, headers_resp, body_resp = http.post("http://www.touchsprite.net/site/login", 3, headers_send, post_escaped)
dialog(status_resp,0)
dialog(headers_resp,0)
if status_resp ~= nil then
dialog(status_resp,0)
dialog(headers_resp,0)
if status_resp == 200 then
dialog(string.len(body_resp),0)
end
--获取响应信息头部指定字段
--方法一
server = http.header(headers_resp, "Server")
dialog(server,0)
--方法二
servers = cjson.decode(headers_resp)
dialog(servers["Server"],0)
end
--用http.get实现下载文件功能
local sz = require("sz")
local cjson = sz.json
local http = sz.i82.http
function downFile(url, path)
status, headers, body = http.get(url)
if status == 200 then
file = io.open(path, "wb")
if file then
file:write(body)
file:close()
return status;
else
return -1;
end
else
return status;
end
end
downFile("http://www.touchsprite.com/img/headline-new.png", "/User/Media/TouchSprite/res/1.png")
脚本实例:
--读取键值
local sz = require("sz")
local plist = sz.plist
local plfilename = "/var/mobile/Library/Caches/com.apple.mobile.installation.plist" --设置plist路径
local tmp2 = plist.read(plfilename) --读取plist文件内容并返回一个TABLE
dialog(tmp2.Metadata.ProductBuildVersion, 0) --显示ProductBuildVersion的键值
--写入键值
local sz = require("sz")
local plist = sz.plist
local plfilename = "/var/mobile/Library/Caches/com.apple.mobile.installation.plist" --设置plist路径
local tmp2 = plist.read(plfilename) --读取plist文件内容并返回一个TABLE
tmp2["Metadata"]["ProductBuildVersion"] = "havonz" --将表中ProductBuildVersion键值改为havonz
plist.write(plfilename, tmp2) --将修改后的表写入PLIST文件
注意事项:
1.PLIST操作需要ts.so插件的支持,请下载ts.so后进行文件操作。
2. 实例代码仅做为参考,实际调试中请将文件路径替换为实际存在的文件路径。
3. 对于个别重要的 PLIST 文件,请谨慎使用写入功能或在运行脚本前进行备份。
4. 需要注意的是,nib 文件作为一种特殊的 plist 文件格式,不能被正确的读取。
函数名称:click
函数功能:单击
脚本实例:
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
p0:click() -- 单击点 p0
p0:click(100) -- 单击点 p0 按下 100 毫秒延迟 弹起
函数名称:dbclick
函数功能:双击
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
p0:dbclick(100, 200) -- 双击点 p0 按下 100毫秒延迟 弹起 延迟 200 毫秒 重复第一步
函数名称:touchMoveTo
函数功能:精确滑动
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
p0:touchMoveTo(p1, 2, 500, 1) -- 从点 p0 滑动到 p1 , 后面三个可选参数依次为:步长、弹起延迟、每步延迟
函数名称:angleBetween
函数功能:计算角度
脚本实例:
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
dialog(" p0 到 p1 的角度为: "..p0:angleBetween(p1), 0)
函数名称:distanceBetween
函数功能:计算距离
脚本实例:
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
dialog(" p0 到 p1 的距离为: "..p0:distanceBetween(p1), 0)
函数名称:polarProjection
函数功能:根据角度和距离找点
脚本实例:
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
dialog(" p0 往 30 度方向前进 200 距离单位的另一个点: "..tostring(p0:polarProjection(200, 30)), 0)
函数名称:cmpColor
函数功能:计算颜色相似度
脚本实例:
local sz = require("sz")
local pos = sz.pos
local p0 = pos(100, 150, 0x123456)
local p1 = pos(556, 400, 0x654321)
dialog("颜色 0x102030 与颜色 0x122232 的相似度为: "..pos.cmpColor( 0x102030, 0x122232), 0)
dialog("p0 结构的颜色与颜色 0x123456 相似度为: "..p0:cmpColor(0x123456), 0)
设备 | 屏幕尺寸 | 分辨率 (pt) | Render | 分辨率 (px) | PPI |
---|---|---|---|---|---|
iPhone4(S)/iPod Touch4G | 3.5 | 320x480 | @2x | 640x960 | 330 |
iPhone 5(S/C)/SE/iPod Touch5G(6G) | 4.0 | 320x568 | @2x | 640x1136 | 326 |
iPhone 6(S) | 4.7 | 375x667 | @2x | 750x1334 | 326 |
iPhone 6(S) Plus | 5.5 | 414x736 | @3x | 1242x2208 | 401 |
iPad 1/2 | 9.7 | 768x1024 | @1x | 768x1024 | 163 |
iPad mini | 7.9 | 768x1024 | @1x | 768x1024 | 163 |
TheNewiPad/iPad 4/Air/Air2 | 9.7 | 768x1024 | @2x | 1536x2048 | 264 |
iPad mini 2/mini 3/mini 4 | 7.9 | 768x1024 | @2x | 1536x2048 | 324 |
iPad Pro | 9.7/12.9 | 768x1024 | @2x | 2048×2732 | 264 |
函数名 | 描述 | 示例 | 结果 |
---|---|---|---|
pi | 圆周率 | math.pi | 3.1415926535898 |
abs | 取绝对值 | math.abs(-2012) | 2012 |
ceil | 向上取整 | math.ceil(9.1) | 10 |
floor | 向下取整 | math.floor(9.9) | 9 |
max | 取参数最大值 | math.max(2,4,6,8) | 8 |
min | 取参数最小值 | math.max(2,4,6,8) | 2 |
pow | 计算x的y次幂 | math.pow(2,16) | 65536 |
sqrt | 开平方 | math.sqrt(65536) | 256 |
modf | 取整数和小数部分 | math.modf(20.12) | 20 0.12 |
randomseed | 设随机数种子 | math.randomseed(os.time()) | |
random | 取随机数 | math.random(5,90) | 5 ~ 90 |
rad | 角度转弧度 | math.rad(180) | 3.1415926535898 |
deg | 弧度转角度 | math.deg(math.pi) | 180 |
exp | e的x次方 | math.exp(4) | 54.598150033144 |
log | 计算x的自然对数 | math.log(54.598150033144) | 4 |
log10 | 计算10为底,x的对数 | math.log10(1000) | 3 |
frexp | 将参数拆成 x * (2 ^ y) 的形式 | math.frexp(160) | 0.625 8 |
ldexp | 计算x * (2 ^ y) | math.ldexp(0.625,8) | 160 |
sin | 正弦 | math.sin(math.rad(30)) | 0.5 |
cos | 余弦 | math.cos(math.rad(60)) | 0.5 |
tan | 正切 | math.tan(math.rad(45)) | 1 |
asin | 反正弦 | math.deg(math.asin(0.5)) | 30 |
acos | 反余弦 | math.deg(math.acos(0.5)) | 60 |
atan | 反正切 | math.deg(math.atan(1)) | 45 |
如果您安装了以下插件导致触动精灵服务使用异常,请在Cydia 中卸载该插件后重新安装客户端。
冲突插件 | 导致问题 |
---|---|
Stashing(内存修正插件) | 会导致帮你玩无法注册和登录账号,提示文件获取失败 |
StatusHUD2 插件 | 会导致脚本showUI无法弹 |
PS/易天行(伪装地理位置插件) | 会导致点击失效或服务无法启动 |
CCSettings(修改美化控制中心插件) | 会导致脚本showUI无法弹出 |
协奏助手 | 会导致点击失效 |
按键精灵iOS | 会导致UI弹出后点击【取消】【确定】无反应 |
xxplugin - coc/cok(xxplugin 系列插件) | 会导致点击失效或服务无法启动 |
XY苹果助手 | 会导致点击失效或服务无法启动 |
键名 | 描述 | 键值 |
---|---|---|
KEYCODE_HOME | 按键Home | 3 |
KEYCODE_BACK | 返回键 | 4 |
KEYCODE_CALL | 拨号键 | 5 |
KEYCODE_ENDCALL | 挂机键 | 6 |
KEYCODE_VOLUME_UP | 音量增加键 | 24 |
KEYCODE_VOLUME_DOWN | 音量减小键 | 25 |
KEYCODE_POWER | 电源键 | 26 |
KEYCODE_CAMERA | 拍照键 | 27 |
KEYCODE_FOCUS | 拍照对焦键 | 80 |
KEYCODE_MENU | 菜单键 | 82 |
KEYCODE_NOTIFICATION | 通知键 | 83 |
KEYCODE_SEARCH | 搜索键 | 84 |
KEYCODE_MUTE | 话筒静音键 | 91 |
KEYCODE_VOLUME_MUTE | 扬声器静音键 | 164 |
键名 | 描述 | 键值 |
---|---|---|
KEYCODE_DPAD_UP | 导航键 向上 | 19 |
KEYCODE_DPAD_DOWN | 导航键 向下 | 20 |
KEYCODE_DPAD_LEFT | 导航键 向左 | 21 |
KEYCODE_DPAD_RIGHT | 导航键 向右 | 22 |
KEYCODE_DPAD_CENTER | 导航键 确定键 | 23 |
KEYCODE_TAB | Tab键 | 61 |
KEYCODE_ENTER | 回车键 | 66 |
KEYCODE_DEL | 退格键 | 67 |
KEYCODE_PAGE_UP | 向上翻页键 | 92 |
KEYCODE_PAGE_DOWN | 向下翻页键 | 93 |
KEYCODE_ESCAPE | ESC键 | 111 |
KEYCODE_FORWARD_DEL | 删除键 | 112 |
KEYCODE_CAPS_LOCK | 大写锁定键 | 115 |
KEYCODE_SCROLL_LOCK | 滚动锁定键 | 116 |
KEYCODE_BREAK | Break/Pause键 | 121 |
KEYCODE_MOVE_HOME | 光标移动到开始键 | 122 |
KEYCODE_MOVE_END | 光标移动到末尾键 | 123 |
KEYCODE_INSERT | 插入键 | 124 |
KEYCODE_NUM_LOCK | 小键盘锁 | 143 |
KEYCODE_ZOOM_IN | 放大键 | 168 |
KEYCODE_ZOOM_OUT | 缩小键 | 169 |
键名 | 描述 | 键值 |
---|---|---|
KEYCODE_0 | 按键'0' | 7 |
KEYCODE_1 | 按键'1' | 8 |
KEYCODE_2 | 按键'2' | 9 |
KEYCODE_3 | 按键'3' | 10 |
KEYCODE_4 | 按键'4' | 11 |
KEYCODE_5 | 按键'5' | 12 |
KEYCODE_6 | 按键'6' | 13 |
KEYCODE_7 | 按键'7' | 14 |
KEYCODE_8 | 按键'8' | 15 |
KEYCODE_9 | 按键'9' | 16 |
KEYCODE_A | 按键'A' | 29 |
KEYCODE_B | 按键'B' | 30 |
KEYCODE_C | 按键'C' | 31 |
KEYCODE_D | 按键'D' | 32 |
KEYCODE_E | 按键'E' | 33 |
KEYCODE_F | 按键'F' | 34 |
KEYCODE_G | 按键'G' | 35 |
KEYCODE_H | 按键'H' | 36 |
KEYCODE_I | 按键'I' | 37 |
KEYCODE_J | 按键'J' | 38 |
KEYCODE_K | 按键'K' | 39 |
KEYCODE_L | 按键'L' | 40 |
KEYCODE_M | 按键'M' | 41 |
KEYCODE_N | 按键'N' | 42 |
KEYCODE_O | 按键'O' | 43 |
KEYCODE_P | 按键'P' | 44 |
KEYCODE_Q | 按键'Q' | 45 |
KEYCODE_R | 按键'R' | 46 |
KEYCODE_S | 按键'S' | 47 |
KEYCODE_T | 按键'T' | 48 |
KEYCODE_U | 按键'U' | 49 |
KEYCODE_V | 按键'V' | 50 |
KEYCODE_W | 按键'W' | 51 |
KEYCODE_X | 按键'X' | 52 |
KEYCODE_Y | 按键'Y' | 53 |
KEYCODE_Z | 按键'Z' | 54 |
- 设置 - (界面底部)其他应用管理 - 触动精灵 - 应用详情界面上滑 - (底部)权限管理 - 悬浮窗管理 - (弹出的底部菜单)选择允许
- 安全中心 - 授权管理 - 应用权限管理 - 小精灵名称 - 显示悬浮窗 - 开启
- 设置 - 全部设置 - 隐私和安全- 通知管理 - 悬浮窗管理 - 小精灵名称 - 打开开关
-手机管家 - 悬浮窗管理 - 小精灵名称 - 开启悬浮窗
- 设置 - (左侧栏)应用管理 - 小精灵名称 - 权限管理- 弹框消息一览 - 点击右侧按钮 - 按钮为绿色时为打开状态
-安全中心 - 授权管理 - 小精灵名称 - 悬浮窗 - 开启
- 安全中心 - 权限隐私 - 应用权限管理 - 悬浮窗管理 - 小精灵名称 - 打开开关
- 管家 - 权限管理 - 应用权限管理 - 权限管理 - 小精灵名称 - 显示悬浮窗 - 开启
- 安全中心 - 应用程序权限管理 - 其他 - 桌面悬浮窗 - 小精灵名称 - 打开开关
- 三星
- vivo
- 酷派
- 金立
- WinSCP:http://pan.baidu.com/s/1o6jtP7G
- 简体中文语言包:http://pan.baidu.com/s/15xaEy
- Putty:http://pan.baidu.com/s/1mgslwX6
- VCredist 2010:http://pan.baidu.com/s/1sjjTFQH
- NET Framework 4:http://www.microsoft.com/zh-cn/download/details.aspx?id=17718
- 触动精灵本地OCR简体中文识别库:http://pan.baidu.com/s/1qW2mDWC
- 触动精灵本地OCR英文数字识别库:http://pan.baidu.com/s/1eQ3nbZs
参数 | 说明 |
---|---|
prefs:root=WIFI | WIFI |
prefs:root=INTERNET_TETHERING | 个人热点 |
prefs:root=MOBILE_DATA_SETTINGS_ID | 蜂窝设置 |
prefs:root=Privacy | 隐私 |
prefs:root=General&path | 通用 |
prefs:root=LOCATION_SERVICES | 定位服务 |
prefs:root=VPN | VPN |
prefs:root=General&path=About | 关于 |
prefs:root=General&path=ACCESSIBILITY | 辅助功能 |
prefs:root=AIRPLANE_MODE | 飞行模式 |
prefs:root=General&path=AUTOLOCK | 自动锁屏时间 |
prefs:root=General&path=USAGE | 用量 |
prefs:root=Brightness | 亮度 |
prefs:root=General&path=Bluetooth | 蓝牙 |
prefs:root=General&path=DATE_AND_TIME | 日期和时间 |
prefs:root=FACETIME | Facetime设置 |
prefs:root=General&path=Keyboard | 键盘设置 |
prefs:root=CASTLE | Icloud |
prefs:root=CASTLE&path=STORAGE_AND_BACKUP | 备份 |
prefs:root=General&path=INTERNATIONAL | 语言与地区设置 |
prefs:root=ACCOUNT_SETTINGS | 账户设置 |
prefs:root=MUSIC | 音乐 |
prefs:root=MUSIC&path=EQ | EQ均衡器 |
prefs:root= | 设置 |
prefs:root=NOTES | 备忘录 |
prefs:root=NOTIFICATIONS_ID | 通知 |
prefs:root=Phone | 电话设置 |
prefs:root=Photos | 照片与相机设置 |
prefs:root=General&path=Reset | 还原 |
prefs:root=Sounds&path=Ringtone | 铃声设置 |
prefs:root=Safari | Safari |
prefs:root=Sounds | 声音 |
prefs:root=General&path=SOFTWARE_UPDATE_LINK | 系统更新 |
prefs:root=STORE | STORE设置 |
prefs:root=VIDEO | 视频设置 |
prefs:root=Wallpaper | 壁纸设置 |
按键码 | 说明 |
---|---|
"a" | a or A |
"b" | b or B |
"c" | c or C |
"d" | d or D |
"e" | e or E |
"f" | f or F |
"g" | g or G |
"h" | h or H |
"i" | i or I |
"j" | j or J |
"k" | k or K |
"l" | l or L |
"m" | m or M |
"n" | n or N |
"o" | o or O |
"p" | p or P |
"q" | q or Q |
"r" | r or R |
"s" | s or S |
"t" | t or T |
"u" | u or U |
"v" | v or V |
"w" | w or W |
"x" | x or X |
"y" | y or Y |
"z" | z or Z |
按键码 | 说明 |
---|---|
"0" | 1 or ! |
"1" | 2 or @ |
"2" | 3 or # |
"3" | 4 or $ |
"4" | 5 or % |
"5" | 6 or ^ |
"6" | 7 or & |
"7" | 8 or * |
"8" | 9 or ( |
"9" | 0 or ) |
按键码 | 说明 |
---|---|
"Hyphen" | - or _ |
"EqualSign" | = or + |
"OpenBracket" | [ or { |
"CloseBracket" | ] or } |
"Backslash" | \ or l |
"NonUSPound" | Non-US # or _ |
"Semicolon" | ; or : |
"Quote" | ' or " |
"GraveAccentAndTilde" | Grave Accent and Tilde |
"Comma" | , or < |
"Period" | . or > |
"Slash" | / or ? |
"ReturnOrEnter" /* Return (Enter) */
"Escape" /* Escape */
"DeleteOrBackspace" /* Delete (Backspace) */
"Tab" /* Tab */
"Spacebar" /* Spacebar */
"CapsLock" /* Caps Lock */
"F1" /* F1 */
"F2" /* F2 */
"F3" /* F3 */
"F4" /* F4 */
"F5" /* F5 */
"F6" /* F6 */
"F7" /* F7 */
"F8" /* F8 */
"F9" /* F9 */
"F10" /* F10 */
"F11" /* F11 */
"F12" /* F12 */
"PrintScreen" /* Print Screen */
"ScrollLock" /* Scroll Lock */
"Pause" /* Pause */
"Insert" /* Insert */
"Home" /* Home */
"PageUp" /* Page Up */
"DeleteForward" /* Delete Forward */
"End" /* End */
"PageDown", /* Page Down */
"RightArrow" /* Right Arrow */
"LeftArrow" /* Left Arrow */
"DownArrow" /* Down Arrow */
"UpArrow" /* Up Arrow */
"KeypadNumLock" /* Keypad NumLock or Clear */
"KeypadSlash" /* Keypad / */
"KeypadAsterisk" /* Keypad * */
"KeypadHyphen" /* Keypad - */
"KeypadPlus" /* Keypad + */
"KeypadEnter" /* Keypad Enter */
"Keypad1" /* Keypad 1 or End */
"Keypad2" /* Keypad 2 or Down Arrow */
"Keypad3" /* Keypad 3 or Page Down */
"Keypad4" /* Keypad 4 or Left Arrow */
"Keypad5" /* Keypad 5 */
"Keypad6" /* Keypad 6 or Right Arrow */
"Keypad7" /* Keypad 7 or Home */
"Keypad8" /* Keypad 8 or Up Arrow */
"Keypad9" /* Keypad 9 or Page Up */
"Keypad0" /* Keypad 0 or Insert */
"KeypadPeriod" /* Keypad . or Delete */
"NonUSBackslash" /* Non-US \ or | */
"Application" /* Application */
"Power" /* Power */
"EqualSign" /* Keypad = */
"F13" /* F13 */
"F14" /* F14 */
"F15" /* F15 */
"F16" /* F16 */
"F17" /* F17 */
"F18" /* F18 */
"F19" /* F19 */
"F20" /* F20 */
"F21" /* F21 */
"F22" /* F22 */
"F23" /* F23 */
"F24" /* F24 */
"Execute" /* Execute */
"Help" /* Help */
"Menu" /* Menu */
"Select" /* Select */
"Stop" /* Stop */
"Again" /* Again */
"Undo" /* Undo */
"Cut" /* Cut */
"Copy" /* Copy */
"Paste" /* Paste */
"Find" /* Find */
"Mute" /* Mute */
"VolumeUp" /* Volume Up */
"VolumeDown" /* Volume Down */
"LockingCapsLock" /* Locking Caps Lock */
"LockingNumLock" /* Locking Num Lock */
"LockingScrollLock" /* Locking Scroll Lock */
"Comma" /* Keypad Comma */
"EqualSignAS400", /* Keypad Equal Sign for AS/400 */
"International1", /* International1 */
"International2", /* International2 */
"International3", /* International3 */
"International4", /* International4 */
"International5", /* International5 */
"International6", /* International6 */
"International7", /* International7 */
"International8", /* International8 */
"International9", /* International9 */
"LANG1" /* LANG1 */
"LANG2" /* LANG2 */
"LANG3" /* LANG3 */
"LANG4" /* LANG4 */
"LANG5" /* LANG5 */
"LANG6" /* LANG6 */
"LANG7" /* LANG7 */
"LANG8" /* LANG8 */
"LANG9" /* LANG9 */
"AlternateErase" /* AlternateErase */
"SysReqOrAttention" /* SysReq/Attention */
"Cancel" /* Cancel */
"Clear" /* Clear */
"Prior" /* Prior */
"Return" /* Return */
"Separator" /* Separator */
"Out" /* Out */
"Oper" /* Oper */
"ClearOrAgain" /* Clear/Again */
"CrSelOrProps" /* CrSel/Props */
"ExSel" /* ExSel */
"LeftControl" /* Left Control */
"LeftShift" /* Left Shift */
"LeftAlt" /* Left Alt */
"LeftGUI" /* Left GUI */
"RightControl" /* Right Control */
"RightShift" /* Right Shift */
"RightAlt" /* Right Alt */
"RightGUI" /* Right GUI */
"ErrorRollOver", /* ErrorRollOver */
"POSTFail", /* POSTFail */
"ErrorUndefined", /* ErrorUndefined */
```